如何合并携带多个变量和多个组的多个统计信息的数据框?

How do I combine data frames carrying information about multiple statistics across multiple variables and multiple groups?

我正在使用以下代码从 mtcars 相关性计算 Spearman r 值:

 library(plyr)
 library(dplyr)
 mtcars[mtcars==3.440] <- NA
 mtcars[mtcars==4.22] <- NA
 mtcars[mtcars==18.90] <- NA
 selected <- select(mtcars, "cyl", "disp", "wt")
 mtcars$cyl <- as.factor(mtcars$cyl)
 for (i in "cyl") {
 co <- ddply(na.omit(selected), i, function(adf) cor(adf[,2], adf[,3], method ="spearman"))
   names(co) <- c('cyl',paste('CorCol',i, sep='_'))
   if(exists('odf')) { 
     odf <- merge(odf, co, by='cyl', all=TRUE)} else {
     odf <- co } }
 colnames(odf)[colnames(odf)=="CorCol_cyl"] <- "wt"
 selected <- select(mtcars, "cyl", "disp", "qsec")
 for (i in "cyl") {
 co <- ddply(na.omit(selected), i, function(adf) cor(adf[,2], adf[,3], method ="spearman"))
   names(co) <- c('cyl',paste('CorCol',i, sep='_'))
   if(exists('odf')) { 
     odf <- merge(odf, co, by='cyl', all=TRUE)} else {
     odf <- co } }
 colnames(odf)[colnames(odf)=="CorCol_cyl"] <- "qsec"
 selected <- select(mtcars, "cyl", "disp", "drat")
 for (i in "cyl") {
 co <- ddply(na.omit(selected), i, function(adf) cor(adf[,2], adf[,3], method ="spearman"))
   names(co) <- c('cyl',paste('CorCol',i, sep='_'))
   if(exists('odf')) { 
     odf <- merge(odf, co, by='cyl', all=TRUE)} else {
     odf <- co } }
 colnames(odf)[colnames(odf)=="CorCol_cyl"] <- "drat"

这导致此数据框具有 Spearman r 值:

 > odf
     cyl  wt         qsec        drat
 1   4    0.8181818  0.29696970  -0.41337577
 2   6    0.7181848  0.92763366  -0.29629630
 3   8    0.4453704  0.07734925  -0.05153203

这正是我想要的。但是,我也有兴趣生成两个额外的数据帧,一个是相同的,但它显示的不是 Spearman r 值,而是 Spearman p 值。另一个也一样,但是它显示的是样本量,即每个样本的比较次数。

如果有任何建议,我将不胜感激。谢谢。

我提出了一个 解决方案,它利用 list-columns(一次处理所有三个 cyl 组):

  • 我在三个 cyl 组上使用 group_by() 到 "loop",而不是显式 for 循环。
  • 我使用 cor.test,它在一步中给出了相关性和 p-value。 (请注意,由于 mtcars 数据集中的关系,我没有使用 Spearman 相关性。您可以根据您的实际数据集的需要进行调整。)
  • cor.test() 进入 summarize(),对于 cyl.
  • 的每个唯一值,将数据框减少到一行(具有相关性等)
  • 我在 summarize() 中使用 list(),这会创建 list-columns.
  • 我使用 broom::tidy() 来很好且一致地格式化 cor.test() 的输出。
  • unnest() list-columns 取回一个没有list-columns的普通数据帧。
  • 最后 select() 只是 re-orders 列,以便在下面的输出中显示最相关的列。

如果你不熟悉但对这些工具感兴趣,我建议你看一看 R for Data Science 这本书,尤其是 Chapter 25 (Many Models).

library("tidyverse")
mtcars %>% 
    group_by(cyl) %>% 
    summarize(n = n(),
              drat = list(cor.test(disp, drat, use = "pair")),
              wt   = list(cor.test(disp, wt,   use = "pair")),
              qsec = list(cor.test(disp, qsec, use = "pair"))) %>% 
    mutate_at(vars(drat, wt, qsec), ~map(.x, ~broom::tidy(.x))) %>% 
    unnest(drat, wt, qsec, .sep = "_") %>% 
    select(cyl, n, ends_with("estimate"), ends_with("p.value"), everything())
#> # A tibble: 3 x 26
#>     cyl     n drat_estimate wt_estimate qsec_estimate drat_p.value
#>   <dbl> <int>         <dbl>       <dbl>         <dbl>        <dbl>
#> 1     4    11       -0.500        0.857         0.328       0.117 
#> 2     6     7       -0.831        0.473         0.789       0.0205
#> 3     8    14       -0.0922       0.755         0.195       0.754 
#> # ... with 20 more variables: wt_p.value <dbl>, qsec_p.value <dbl>,
#> #   drat_statistic <dbl>, drat_parameter <int>, drat_conf.low <dbl>,
#> #   drat_conf.high <dbl>, drat_method <chr>, drat_alternative <chr>,
#> #   wt_statistic <dbl>, wt_parameter <int>, wt_conf.low <dbl>,
#> #   wt_conf.high <dbl>, wt_method <chr>, wt_alternative <chr>,
#> #   qsec_statistic <dbl>, qsec_parameter <int>, qsec_conf.low <dbl>,
#> #   qsec_conf.high <dbl>, qsec_method <chr>, qsec_alternative <chr>

前六行也可以这样写:

mtcars %>% 
    add_count(cyl) %>% 
    group_by(cyl, n) %>% 
    summarise_at(vars(drat, wt, qsec), ~list(cor.test(., disp)))