R:按组计算相关性


17

在R中,我有一个数据帧,包括一个类别标签C(一个因数)和两个测量值M1M2。如何计算每个类别中M1M2之间的相关性?

理想情况下,我将返回一个数据帧,其中每个类一行一行,两列:类标签C和相关性。

Answers:


20

打包plyr是必经之路。

这是一个简单的解决方案:

xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
head(xx)

require(plyr)
func <- function(xx)
{
return(data.frame(COR = cor(xx$a, xx$b)))
}

ddply(xx, .(group), func)

输出将是:

  group         COR
1     1  0.05152923
2     2 -0.15066838
3     3 -0.04717481
4     4  0.07899114

1
(+1)不错的plyr包裹,不是吗?:)
chl

这很好。感谢您指出plyr包装!您能解释一下“。(group)”语法吗?
NPE

2
艾克斯-当然。这意味着“通过。()之间的变量拆分数据,并在每个子集上执行该功能”。为了使其包含更多变量,您应该简单地使用以下语法:。(var1,var2,var3)。这就像按var1,var2和var3级别的每种组合切割数据一样。并在每次切割时执行您的功能。该软件包由Hadley(也是ggplot2的作者)维护,因此我相信它将继续发展。
塔尔·加利里

2
哦,顺便说一句,你也可以使用plyr与并行的几个核心计算(几乎是自动),请参阅:r-statistics.com/2010/09/...
塔尔加利利

1
这是一个很好的答案,但令我惊讶的是,没有内置的解决方案,像cor(x,y,by = z)这样的直观提示……
Waldir Leoncio

12

如果您倾向于在基本软件包中使用by函数,则可以使用函数,然后重新组装数据:

xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
head(xx)

# This returns a "by" object
result <- by(xx[,2:3], xx$group, function(x) {cor(x$a, x$b)})

# You get pretty close to what you want if you coerce it into a data frame via a matrix
result.dataframe <- as.data.frame(as.matrix(result))

# Add the group column from the row names
result.dataframe$C <- rownames(result)

1
很好,谢谢!我一直在尝试by,但无法弄清楚如何将结果转换为数据框。
NPE

9

使用基本包和Tal的示例数据的另一个示例:

DataCov <- do.call( rbind, lapply( split(xx, xx$group),
             function(x) data.frame(group=x$group[1], mCov=cov(x$a, x$b)) ) )

优雅的解决方案Joshue。您是否认为在某些情况下,一种解决方案比另一种更好?
Tal Galili 2010年

2
我认为这是优先考虑的问题。我的示例从本质上讲是plyr做什么的,但是它虽然没有那么干净,但可以为您提供更好的控制。如果一种解决方案具有更好的时间/内存配置文件,我的看法将会改变。我还没有比较它们。
约书亚·乌尔里希

这如何返回相关性?

2

使用data.table比dplyr短

dt <- data.table(xx)
dtCor <- dt[, .(mCor = cor(M1,M2)), by=C]

0

这是一种类似的方法,还将为您提供一个表格,其中包含每个相关性的n和p值(为方便起见,四舍五入到小数点后三位):

library(Hmisc)
corrByGroup <- function(xx){
  return(data.frame(cbind(correl = round(rcorr(xx$a, xx$b)$r[1,2], digits=3),
                          n = rcorr(xx$a, xx$b)$n[1,2],
                          pvalue = round(rcorr(xx$a, xx$b)$P[1,2], digits=3))))
}

0

这是一个使用dplyr软件包的更现代的解决方案(问问题时尚不存在):

构造输入:

xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )

计算相关性:

library(dplyr)
xx %>%
  group_by(group) %>%
  summarize(COR=cor(a,b))

输出:

Source: local data frame [4 x 2]

  group         COR
  (int)       (dbl)
1     1  0.05112400
2     2  0.14203033
3     3 -0.02334135
4     4  0.10626273
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.