2012-01-09 5 views

답변

17

어떻게 기본 R 솔루션 이것에 대해 : 다음

df <- data.frame(group = rep(c("G1", "G2"), each = 10), 
       var1 = rnorm(20), 
       var2 = rnorm(20)) 

r <- by(df, df$group, FUN = function(X) cor(X$var1, X$var2, method = "spearman")) 
# df$group: G1 
# [1] 0.4060606 
# ------------------------------------------------------------ 
# df$group: G2 
# [1] 0.1272727 

그리고, 당신은 data.frame의 형태로 결과를 원하는 경우 :

data.frame(group = dimnames(r)[[1]], corr = as.vector(r)) 
# group  corr 
# 1 G1 0.4060606 
# 2 G2 0.1272727 

을 편집 : plyr 기반 솔루션을 선호하는 경우 여기에 하나 :

여기
library(plyr) 
ddply(df, .(group), summarise, "corr" = cor(var1, var2, method = "spearman")) 
+0

신속한 답변을 주셔서 감사합니다. 그들은 모두 일했다! ;-) – user1009166

+0

(+1) 좋은 답변입니다. 'r - by (df, df $ group, FUN = function (X) cor (df [, - 1], method = "spearman"))'? – MYaseen208

+0

@ MYaseen208. 감사. 코드는 약간 다른 결과를 반환합니다. 나는 그 이름을 알지 못하지만, 각 셀의 상관 관계를 제외하고는 분산 - 공분산 행렬과 같습니다. 내가 사용한 코드는 대신 각 그룹에 대해 단일 스칼라 상관 관계를 반환합니다. –

5

617,451,515,그것을 할 수있는 또 다른 방법 :

# split the data by group then apply spearman correlation 
# to each element of that list 
j <- lapply(split(df, df$group), function(x){cor(x[,2], x[,3], method = "spearman")}) 

# Bring it together 
data.frame(group = names(j), corr = unlist(j), row.names = NULL) 

내 방법, 조쉬의 방법을 비교하고, plyr 솔루션은 rbenchmark를 사용 : 출력을 제공

Dason <- function(){ 
    # split the data by group then apply spearman correlation 
    # to each element of that list 
    j <- lapply(split(df, df$group), function(x){cor(x[,2], x[,3], method = "spearman")}) 

    # Bring it together 
    data.frame(group = names(j), corr = unlist(j), row.names = NULL) 
} 

Josh <- function(){ 
    r <- by(df, df$group, FUN = function(X) cor(X$var1, X$var2, method = "spearman")) 
    data.frame(group = attributes(r)$dimnames[[1]], corr = as.vector(r)) 
} 

plyr <- function(){ 
    ddply(df, .(group), summarise, "corr" = cor(var1, var2, method = "spearman")) 
} 


library(rbenchmark) 
benchmark(Dason(), Josh(), plyr()) 

> benchmark(Dason(), Josh(), plyr()) 
    test replications elapsed relative user.self sys.self user.child sys.child 
1 Dason()   100 0.19 1.000000  0.19  0   NA  NA 
2 Josh()   100 0.24 1.263158  0.22  0   NA  NA 
3 plyr()   100 0.51 2.684211  0.52  0   NA  NA 

그래서 내 방법이 약간 빨라 보이지만 많이는 아닙니다. Josh의 방법이 좀 더 직관적이라고 생각합니다. 플라이 솔루션은 코드 작성이 가장 쉽지만 가장 빠르지는 않습니다 (하지만 훨씬 편리합니다)!

+0

'벤치 마크'로 테스트 해 주셔서 감사드립니다. +1하기. 몇 가지 추가 의견이 있습니다. (1) 벤치 마크를 반복적으로 호출 할 때'lapply (split (...) '와'by (...)'접근법의 일반적인 차이점은 7-10 % 정도입니다. (2) 관심이 있다면 더 많은 것을 추구하면서 아마도 1000 개 이상의 그룹과 1e6 + 행을 가진 몇몇 큰 데이터 프레임에서 세 가지 방법을 테스트하는 것이 더 유용 할 것입니다 .. –

+0

Dason도 시간을내어 감사합니다 !! – user1009166

3

많은 수의 그룹에 대해 효율적인 솔루션을 원한다면 data.table이 좋습니다.

library(data.table) 
DT <- as.data.table(df) 
setkey(DT, group) 
DT[,list(corr = cor(var1,var2,method = 'spearman')), by = group] 
+0

+1'setkey keyed-by는 큰 그룹이 많은 매우 큰 데이터 세트 (예 : 1e7 rows +)의 경우 키가없는 것보다 빠릅니다. 키가없는 것은 이미 매우 빠릅니다. –