행렬 또는 데이터 프레임의 모든 행에 함수 적용
내가 2 행렬과 2 벡터를 인수 중 하나로 취하는 함수가 있다고 가정하십시오. 행렬의 각 행에 함수를 적용하고 n- 벡터를 얻고 싶습니다. R에서 이것을하는 방법?
예를 들어, 세 점에서 2D 표준 정규 분포의 밀도를 계산하려고합니다.
bivariate.density(x = c(0, 0), mu = c(0, 0), sigma = c(1, 1), rho = 0){
exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+x[2]^2/sigma[2]^2-2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
}
out <- rbind(c(1, 2), c(3, 4), c(5, 6))
의 각 행에 함수를 적용하는 방법은 out
무엇입니까?
지정한 방식으로 함수에 포인트 이외의 다른 인수에 대한 값을 전달하는 방법은 무엇입니까?
당신은 단순히 apply()
기능을 사용합니다 :
R> M <- matrix(1:6, nrow=3, byrow=TRUE)
R> M
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
R> apply(M, 1, function(x) 2*x[1]+x[2])
[1] 4 10 16
R>
이것은 행렬을 취하여 (행리 한) 함수를 각 행에 적용합니다. 함수에 추가 인수를 네 번째, 다섯 번째, ... 인수로 전달합니다 apply()
.
경우 당신은 합계 또는 사용한다는 의미는 일반적인 기능을 적용 할 rowSums
또는 rowMeans
그들이보다 빠른 것부터 apply(data, 1, sum)
접근 방식을. 그렇지 않으면로 고정하십시오 apply(data, 1, fun)
. FUN 인수 뒤에 추가 인수를 전달할 수 있습니다 (Dirk에서 이미 제안한대로).
set.seed(1)
m <- matrix(round(runif(20, 1, 5)), ncol=4)
diag(m) <- NA
m
[,1] [,2] [,3] [,4]
[1,] NA 5 2 3
[2,] 2 NA 2 4
[3,] 3 4 NA 5
[4,] 5 4 3 NA
[5,] 2 1 4 4
그런 다음 다음과 같이 할 수 있습니다.
apply(m, 1, quantile, probs=c(.25,.5, .75), na.rm=TRUE)
[,1] [,2] [,3] [,4] [,5]
25% 2.5 2 3.5 3.5 1.75
50% 3.0 2 4.0 4.0 3.00
75% 4.0 3 4.5 4.5 4.00
다음은 행렬의 각 행에 함수를 적용하는 간단한 예입니다. (여기서 적용된 함수는 모든 행을 1로 정규화합니다.)
참고 : 로부터 결과는 apply()
해야했습니다 전치 사용하여 t()
입력 행렬과 동일한 레이아웃을 얻을 A
.
A <- matrix(c(
0, 1, 1, 2,
0, 0, 1, 3,
0, 0, 1, 3
), nrow = 3, byrow = TRUE)
t(apply(A, 1, function(x) x / sum(x) ))
결과:
[,1] [,2] [,3] [,4]
[1,] 0 0.25 0.25 0.50
[2,] 0 0.00 0.25 0.75
[3,] 0 0.00 0.25 0.75
First step would be making the function object, then applying it. If you want a matrix object that has the same number of rows, you can predefine it and use the object[] form as illustrated (otherwise the returned value will be simplified to a vector):
bvnormdens <- function(x=c(0,0),mu=c(0,0), sigma=c(1,1), rho=0){
exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+
x[2]^2/sigma[2]^2-
2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) *
1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
}
out=rbind(c(1,2),c(3,4),c(5,6));
bvout<-matrix(NA, ncol=1, nrow=3)
bvout[] <-apply(out, 1, bvnormdens)
bvout
[,1]
[1,] 1.306423e-02
[2,] 5.931153e-07
[3,] 9.033134e-15
If you wanted to use other than your default parameters then the call should include named arguments after the function:
bvout[] <-apply(out, 1, FUN=bvnormdens, mu=c(-1,1), rho=0.6)
apply() can also be used on higher dimensional arrays and the MARGIN argument can be a vector as well as a single integer.
Apply does the job well, but is quite slow. Using sapply and vapply could be useful. dplyr's rowwise could also be useful Let's see an example of how to do row wise product of any data frame.
a = data.frame(t(iris[1:10,1:3]))
vapply(a, prod, 0)
sapply(a, prod)
Note that assigning to variable before using vapply/sapply/ apply is good practice as it reduces time a lot. Let's see microbenchmark results
a = data.frame(t(iris[1:10,1:3]))
b = iris[1:10,1:3]
microbenchmark::microbenchmark(
apply(b, 1 , prod),
vapply(a, prod, 0),
sapply(a, prod) ,
apply(iris[1:10,1:3], 1 , prod),
vapply(data.frame(t(iris[1:10,1:3])), prod, 0),
sapply(data.frame(t(iris[1:10,1:3])), prod) ,
b %>% rowwise() %>%
summarise(p = prod(Sepal.Length,Sepal.Width,Petal.Length))
)
Have a careful look at how t() is being used
Another approach if you want to use a varying portion of the dataset instead of a single value is to use rollapply(data, width, FUN, ...)
. Using a vector of widths allows you to apply a function on a varying window of the dataset. I've used this to build an adaptive filtering routine, though it isn't very efficient.
'development' 카테고리의 다른 글
matplotlib에서 특정 포인트 위로 마우스를 가져갈 때 레이블을 표시 할 수 있습니까? (0) | 2020.07.24 |
---|---|
JSON.net : 기본 생성자를 사용하지 않고 직렬화 해제하는 방법? (0) | 2020.07.24 |
fpermissive 플래그는 무엇을합니까? (0) | 2020.07.24 |
WPF에 Main ()이 없습니까? (0) | 2020.07.24 |
std :: array와 std :: vector의 차이점은 무엇입니까? (0) | 2020.07.24 |