聚合相关性 (R::dplyr)

Aggregated Correlation (R::dplyr)

我正在尝试计算数据框不同子集的相关矩阵。我发现这段代码用于计算数据框中 2 个变量之间的相关性:

library(dplyr)
mtcars %>% group_by(cyl) %>% summarise(V1=cor(hp,wt))

但我想计算数据框中几个变量之间的相关矩阵。我希望(最好)将其作为相关矩阵列表返回。类似于:

mtcars %>% group_by(cyl) %>% cor(data.frame(hp,wt,qsec)

我可以用 dplyr 做到这一点吗?

在我看来旧的 bydlply 在这里更好,但如果你真的想使用 dplyr,我认为你可以使用 do:

o <- mtcars %>% group_by(cyl) %>% do(cor=cor(cbind(.$hp, .$wt, .$qsec)))
# Source: local data frame [3 x 2]
# Groups: <by row>

#   cyl        cor
# 1   4 <dbl[3,3]>
# 2   6 <dbl[3,3]>
# 3   8 <dbl[3,3]>

其中 . 指的是过滤后的数据帧。然后你可以做 o$cor[1] 等。我不确定如何从 dplyr 获取列表输出而不是数据帧输出。


使用 plyr:

library(plyr)
dlply(mtcars, .(cyl), function (x) cor(x[, c('hp', 'wt', 'qsec')]))

使用基数 R 和 by:

o <- by(mtcars[, c('hp', 'wt', 'qsec')], mtcars$cyl, cor, simplify=F)

o 属于 class by,但 ?by 说这基本上是一个列表。

length(o) # 3
names(o) # "4" "6" "8" (i.e. the cyl values)
o[[1]] # =cor(hp, wt, qsec) where cyl==4

这是一个老问题,但我在这里更新以防它对人们有帮助。

您可以使用 purrr 包中的函数将包含相关矩阵的 tibble 转换为可以进一步操作的对象列表。

具体来说,扩展@mathematical.coffee提供的答案:

library(tidyverse)
data(mtcars)

mtcars %>% 
  dplyr::group_by(cyl) %>% 
  dplyr::do(cor = cor(cbind(.$hp, .$wt, .$qsec))) %>%
  purrr::transpose() %>%     # <- converts tibble to a row-wise list
  purrr::set_names(nm = purrr::map(., 'cyl')) %>%  # <- use `cyl` as item name
  purrr::map('cor')      # <- extract `cor` from each list item

结果是相关矩阵列表:

$`4`
           [,1]      [,2]       [,3]
[1,]  1.0000000 0.1598761 -0.1783611
[2,]  0.1598761 1.0000000  0.6380214
[3,] -0.1783611 0.6380214  1.0000000

$`6`
           [,1]       [,2]       [,3]
[1,]  1.0000000 -0.3062284 -0.6280148
[2,] -0.3062284  1.0000000  0.8659614
[3,] -0.6280148  0.8659614  1.0000000

$`8`
            [,1]       [,2]       [,3]
[1,]  1.00000000 0.01761795 -0.7554985
[2,]  0.01761795 1.00000000  0.5365487
[3,] -0.75549854 0.53654866  1.0000000

其中的关键部分是 purrr::transpose() 函数,它将 tibble 转换为列列表,然后再将其转换为行列表。