행렬 또는 데이터 프레임의 모든 행에 함수 적용


129

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무엇입니까?

지정한 방식으로 함수에 대한 포인트 외에 다른 인수의 값을 전달하는 방법은 무엇입니까?

답변:


180

다음 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().


감사! 행렬의 행이 함수의 첫 번째 인수가 아니면 어떻게됩니까? 행렬의 각 행이 할당되는 함수의 인수를 지정하는 방법은 무엇입니까?
Tim

도움말을 읽으십시오 apply()-행별로 스윕하고 (두 번째 인수가 1 일 때, 그렇지 않으면 열로) 현재 행 (또는 col)은 항상 첫 번째 인수입니다. 그것이 사물이 정의되는 방식입니다.
Dirk Eddelbuettel 2010

@ 팀 : 당신이 내부 R 기능을 사용하여 행이 첫번째 인수가 아닌 경우 더크했고, 행 위치를 사용자 정의 기능을 같이 할 것입니다 최초의 인수가.
Joris Meys

3
plyr 패키지는 이러한 적용 종류의 다양한 기능을 제공합니다. 또한 병렬 처리를 포함하여 더 많은 기능을 제공합니다.
Paul Hiemstra 2011

6
@ cryptic0이 답변은 늦었지만 Google 직원에게는 적용의 두 번째 인수가 MARGIN인수입니다. 여기서는 행 (의 첫 번째 차원)에 함수를 적용하는 것을 의미합니다 dim(M). 2 인 경우 함수를 열에 적용합니다.
De Novo

17

합계 나 평균과 같은 일반적인 함수를 적용하려면 접근 보다 빠르기 때문에 rowSums또는 을 사용해야합니다 . 그렇지 않으면 . FUN 인수 뒤에 추가 인수를 전달할 수 있습니다 (Dirk이 이미 제안한대로).rowMeansapply(data, 1, sum)apply(data, 1, fun)

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

15

다음은 행렬의 각 행에 함수를 적용하는 간단한 예입니다. (여기서 적용된 함수는 모든 행을 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

6

첫 번째 단계는 함수 객체를 만든 다음 적용하는 것입니다. 같은 수의 행을 가진 행렬 객체를 원하면 그림과 같이 객체를 미리 정의하고 object [] 형식을 사용할 수 있습니다 (그렇지 않으면 반환 된 값이 벡터로 단순화됩니다).

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

기본 매개 변수가 아닌 다른 매개 변수를 사용하려는 경우 함수 뒤에 명명 된 인수를 포함해야합니다.

bvout[] <-apply(out, 1, FUN=bvnormdens, mu=c(-1,1), rho=0.6)

apply ()는 고차원 배열에서도 사용할 수 있으며 MARGIN 인수는 단일 정수일뿐만 아니라 벡터 일 수 있습니다.


4

Apply는 작업을 잘 수행하지만 상당히 느립니다. sapply 및 vapply를 사용하면 유용 할 수 있습니다. dplyr의 rowwise도 유용 할 수 있습니다. 모든 데이터 프레임의 row wise product를 수행하는 방법의 예를 살펴 보겠습니다.

a = data.frame(t(iris[1:10,1:3]))
vapply(a, prod, 0)
sapply(a, prod)

vapply / sapply / apply를 사용하기 전에 변수에 할당하는 것은 시간을 많이 줄여주는 좋은 방법입니다. 마이크로 벤치 마크 결과를 보자

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))
)

t ()가 어떻게 사용되는지주의 깊게 살펴보십시오.


b <- t(iris[1:10, 1:3])및 을 사용한 경우 apply 제품군을 비교하는 것이 더 공정 할 수 있습니다 apply(b, 2 prod).
DaSpeeg

2

단일 값 대신 데이터 세트의 다양한 부분을 사용하려는 경우 또 다른 방법은를 사용하는 것입니다 rollapply(data, width, FUN, ...). 폭 벡터를 사용하면 데이터 세트의 다양한 창에 함수를 적용 할 수 있습니다. 매우 효율적이지는 않지만 적응 형 필터링 루틴을 구축하기 위해 이것을 사용했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.