在dplyr中分组变量的相关矩阵

15

我有一个使用dplyr分组的数据框,其中包含50个数值列,这些列根据其中一列分为不同的组。我想计算所有非分组列与特定列之间的相关矩阵。

以下是使用mtcars数据集的示例:

data(mtcars)
cor(mtcars[,2:11], mtcars[,2])

返回每加仑英里数与其他变量之间的相关性列表。

假设我希望计算每组汽缸的相同相关性,例如:

library(dplyr)
mtcars <-
    mtcars %>%
    group_by(cyl)
我该如何做到这一点?我在考虑类似于什么样的东西
mtcars %>%
    group_by(cyl) %>%
    summarise_each(funs(cor(...))

但我不知道在...中应该放什么,因为我不知道如何在dplyr链中指定一个列。

相关信息Linear model and dplyr - a better solution? 有一个回答与@akrun的答案非常相似。另外,在交叉验证中:https://stats.stackexchange.com/questions/4040/r-compute-correlation-by-group 提供了其他使用不是dplyr的包的解决方案。

1个回答

18
我们可以使用do
library(dplyr)
mtcars %>% 
       group_by(cyl) %>%
       do(data.frame(Cor=t(cor(.[,3:11], .[,3]))))
# A tibble: 3 x 10
# Groups:   cyl [3]
#    cyl Cor.disp Cor.hp Cor.drat Cor.wt Cor.qsec Cor.vs Cor.am Cor.gear Cor.carb
#  <dbl>    <dbl>  <dbl>    <dbl>  <dbl>    <dbl>  <dbl>  <dbl>    <dbl>    <dbl>
#1     4     1.00  0.435  -0.500   0.857    0.328 -0.187 -0.734  -0.0679   0.490 
#2     6     1.00 -0.514  -0.831   0.473    0.789  0.637 -0.637  -0.899   -0.942 
#3     8     1     0.118  -0.0922  0.755    0.195 NA     -0.169  -0.169    0.0615

注意:t 部分由 @Alex 贡献。


或者使用 group_modify

mtcars %>%
    select(-mpg) %>% 
    group_by(cyl) %>%
    group_modify(.f = ~ as.data.frame(t(cor(select(.x, everything()), 
          .x[['disp']]))))
# A tibble: 3 x 10
# Groups:   cyl [3]
#    cyl  disp     hp    drat    wt  qsec     vs     am    gear    carb
#  <dbl> <dbl>  <dbl>   <dbl> <dbl> <dbl>  <dbl>  <dbl>   <dbl>   <dbl>
#1     4  1.00  0.435 -0.500  0.857 0.328 -0.187 -0.734 -0.0679  0.490 
#2     6  1.00 -0.514 -0.831  0.473 0.789  0.637 -0.637 -0.899  -0.942 
#3     8  1     0.118 -0.0922 0.755 0.195 NA     -0.169 -0.169   0.0615

另一个选项是使用acrosssummarise进行操作。创建一个名为'disp1'的新列,其值等于'disp'列,然后按'cyl'分组,在'disp1'上获取从'disp'到'carb'列的cor

 mtcars %>%
     mutate(disp1 = disp) %>%
     group_by(cyl) %>% 
     summarise(across(disp:carb, ~ cor(., disp1)))
# A tibble: 3 x 10
#    cyl  disp     hp    drat    wt  qsec     vs     am    gear    carb
#* <dbl> <dbl>  <dbl>   <dbl> <dbl> <dbl>  <dbl>  <dbl>   <dbl>   <dbl>
#1     4  1.00  0.435 -0.500  0.857 0.328 -0.187 -0.734 -0.0679  0.490 
#2     6  1.00 -0.514 -0.831  0.473 0.789  0.637 -0.637 -0.899  -0.942 
#3     8  1     0.118 -0.0922 0.755 0.195 NA     -0.169 -0.169   0.0615

或者

library(data.table)
d1 <- copy(mtcars)
setnames(setDT(d1)[, as.list(cor(.SD, .SD[[1]])) , cyl, 
                            .SDcols=3:11],  names(d1)[2:11])[]

@PrzemyslawRemin 尝试使用 mtcars %>% group_by(cyl) %>% group_modify(.f = ~as.data.frame(t(cor(.x[2:10], .x[[2]])))) - akrun
@PrzemyslawRemin,看起来我们正在使用disp列(当我们使用索引时会很混乱)。我更新了帖子。 - akrun
谢谢,看起来更短了,但我还有很多阅读要做。disp:carb应该是用来做什么的? - Przemyslaw Remin
你如何获取相应的p值? - Emmanuel Goldstein
2
做得好,继续更新,太棒了。 - Mark White
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接