【问题标题】:How to get summary statistics for multiple variables by multiple groups?如何按多个组获取多个变量的汇总统计信息?
【发布时间】:2016-01-11 14:06:22
【问题描述】:

我知道这个论坛提供了很多关于如何使用aggregateddplydata.table 等选项获取多个组的汇总统计数据(例如均值、se、N)的答案。但是,我不确定如何一次将这些函数应用于多个列。

更具体地说,我想知道如何将以下ddply 命令扩展到多个列(dv1、dv2、dv3),而无需每次都使用不同的变量名重新键入代码。

library(reshape2)
library(plyr)

group1 <- c(rep(LETTERS[1:4], c(4,6,6,8)))
group2 <- c(rep(LETTERS[5:8], c(6,4,8,6)))
group3 <- c(rep(LETTERS[9:10], c(12,12)))
my.dat <- data.frame(group1, group2, group3, dv1=rnorm(24),dv2=rnorm(24),dv3=rnorm(24))
my.dat

data1 <- ddply(my.dat, c("group1", "group2","group3"), summarise,
               N    = length(dv1),
               mean = mean(dv1,na.rm=T),
               sd   = sd(dv1,na.rm=T),
               se   = sd / sqrt(N)
)
data1

如何将此ddply 函数应用于多个列,以便每个结果变量的结果将是 data1、data2、data3...?我认为this 可能是解决方案:

dfm <- melt(my.dat, id.vars = c("group1", "group2","group3"))
lapply(list(.(group1, variable), .(group2, variable),.(group3, variable)), 
   ddply, .data = dfm, .fun = summarize, 
   mean = mean(value), 
   sd = sd(value),
   N=length(value),
   se=sd/sqrt(N))

看起来方向正确,但不完全是我需要的。此解决方案分别提供每个组的统计信息。我需要数据 1 中的结果(例如,第一个聚合组是 A、E 和 I 组的人;第二个是 B、E 和 I 组的人等......)

【问题讨论】:

  • 一种方法(如果您的数据不是太大)是首先使用“measure.vars”作为“c("dv1","dv2","dv3") 来融合您的数据。然后您可以重复使用您的代码,但添加一个按变量拆分并计算价值摘要。
  • 由于您使用cbind 创建数据框,并且它需要一个参数向量(在您的情况下其中一些是字符串),因此所有参数都被转换为字符串。您可以使用以下代码 my.dat &lt;- data.frame(group1, group2, group3, dv1=rnorm(24),dv2=rnorm(24),dv3=rnorm(24)) 更改创建数据框的方式。您应该能够删除对 lapply 的调用以转换为数字。

标签: r aggregate plyr


【解决方案1】:

这是首先重塑数据的示例。我编写了一个自定义函数来提高可读性:

mysummary <- function(x,na.rm=F){
  res <- list(mean=mean(x, na.rm=na.rm),
              sd=sd(x,na.rm=na.rm),
              N=length(x))
  res$se <- res$sd/sqrt(res$N)
  res
}

library(data.table)

res <- melt(setDT(my.dat),id.vars=c("group1","group2","group3"))[,mysummary(value),
    by=.(group1,group2,group3,variable)]

> head(res)
   group1 group2 group3 variable  mean        sd N       se
1:      A      E      I      dv1  9.75  6.994045 4 3.497023
2:      B      E      I      dv1  9.50  7.778175 2 5.500000
3:      B      F      I      dv1 16.00  4.082483 4 2.041241
4:      C      G      I      dv1 14.50 10.606602 2 7.500000
5:      C      G      J      dv1 10.75 10.372239 4 5.186119
6:      D      G      J      dv1 13.00  4.242641 2 3.000000

或者没有自定义函数,感谢@Jaap

melt(setDT(my.dat),
     id=c("group1","group2","group3"))[, .(mean = mean(value),
                                           sd = sd(value),
                                           n = .N,
                                           se = sd(value)/sqrt(.N)),
                                       .(group1, group2, group3, variable)]

【讨论】:

    【解决方案2】:

    如果你不想把melt变成长格式,你也可以这样做:

    library(data.table)
    setDT(my.dat)[, as.list(unlist(lapply(.SD, function(x) list(mean = mean(x),
                                                                sd = sd(x),
                                                                n = .N,
                                                                se = sd(x)/sqrt(.N))))),
                  by = .(group1, group2, group3), .SDcols=c("dv1","dv2","dv3")]
    

    给出:

       group1 group2 group3    dv1.mean    dv1.sd dv1.n     dv1.se    dv2.mean    dv2.sd dv2.n     dv2.se     dv3.mean    dv3.sd dv3.n    dv3.se
    1:      A      E      I  0.09959774 0.4704498     4 0.23522491  0.05020096 0.8098882     4 0.40494412 -0.134137210 0.7832841     4 0.3916420
    2:      B      E      I  0.72726477 0.3651544     2 0.25820315  0.73743314 1.4260172     2 1.00834641 -0.120188202 0.5532434     2 0.3912022
    3:      B      F      I -0.68661572 0.7212631     4 0.36063157  0.06670216 0.7678781     4 0.38393905  0.096275469 0.8993015     4 0.4496508
    4:      C      G      I -0.54577363 0.0798962     2 0.05649515  0.18293371 0.1022325     2 0.07228926 -0.947603264 2.3118016     2 1.6346906
    5:      C      G      J  0.17434075 0.8503874     4 0.42519369 -0.11485558 1.4184031     4 0.70920154 -0.005140781 0.6871591     4 0.3435796
    6:      D      G      J  0.17943465 0.4943486     2 0.34955725 -0.22223273 0.3679613     2 0.26018796 -0.373289114 1.0737512     2 0.7592568
    7:      D      H      J  0.38090937 0.7904832     6 0.32271340  0.02107597 1.0094695     6 0.41211422  0.118277330 0.9024006     6 0.3684035
    

    【讨论】:

      【解决方案3】:

      这是使用dplyr 的解决方案。这会以“宽”格式给出结果(即 dv1、dv2、dv3 的统计数据在同一行)。

      se <- function(x) { sd(x)/sqrt(length(x)) }
      my.dat                                                        %>%
          group_by(group1, group2, group3)                          %>%
          summarise_each(funs(mean, sd, length, se), dv1, dv2, dv3) %>%
          ungroup
      

      如果需要将 dv1、dv2 和 dv3 的统计信息放在不同的行上,可以使用 meltgather(来自 tidyr)进行修改。

      【讨论】:

        猜你喜欢
        • 2012-04-08
        • 2020-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-12
        • 2021-09-27
        • 2019-01-17
        相关资源
        最近更新 更多