如何在 R 中按组汇总数据?

机器算法验证 r 数据转换
2022-02-10 11:51:38

我有这样的 R 数据框:

        age group
1   23.0883     1
2   25.8344     1
3   29.4648     1
4   32.7858     2
5   33.6372     1
6   34.9350     1
7   35.2115     2
8   35.2115     2
9   35.2115     2
10  36.7803     1
...

我需要以下列形式获取数据框:

group mean     sd
1     34.5     5.6
2     32.3     4.2
...

团号可能会有所不同,但可以通过拨打电话获得团号和数量levels(factor(data$group))

应该对数据进行哪些操作以获得结果?

4个回答

这是使用ddply的plyr单行变体

dt <- data.frame(age=rchisq(20,10),group=sample(1:2,20,rep=T))
ddply(dt,~group,summarise,mean=mean(age),sd=sd(age))

这是另一个使用新包data.table的单行变体。

dtf <- data.frame(age=rchisq(100000,10),group=factor(sample(1:10,100000,rep=T)))
dt <- data.table(dtf)
dt[,list(mean=mean(age),sd=sd(age)),by=group]

这个速度更快,尽管这仅在具有 100k 行的表上很明显。配备 2.53 Ghz Core 2 Duo 处理器和 R 2.11.1 的 Macbook Pro 上的计时:

> system.time(aa <- ddply(dtf,~group,summarise,mean=mean(age),sd=sd(age)))
utilisateur     système      écoulé 
      0.513       0.180       0.692 
> system.time(aa <- dt[,list(mean=mean(age),sd=sd(age)),by=group])
utilisateur     système      écoulé 
      0.087       0.018       0.103 

如果我们使用,可以进一步节省setkey

> setkey(dt,group)
> system.time(dt[,list(mean=mean(age),sd=sd(age)),by=group])
utilisateur     système      écoulé 
      0.040       0.007       0.048 

一种可能性是使用聚合函数例如,

aggregate(data$age, by=list(data$group), FUN=mean)[2]

为您提供所需结果的第二列。

由于您正在操作数据框,因此dplyr包可能是更快的方法。

library(dplyr)
dt <- data.frame(age=rchisq(20,10), group=sample(1:2,20, rep=T))
grp <- group_by(dt, group)
summarise(grp, mean=mean(age), sd=sd(age))

或者等效地,使用dplyr/magrittr管道运算符:

library(dplyr)
dt <- data.frame(age=rchisq(20,10), group=sample(1:2,20, rep=T))
group_by(dt, group) %>%
 summarise(mean=mean(age), sd=sd(age))

编辑完全使用管道运算符:

library(dplyr)
data.frame(age=rchisq(20,10), group=sample(1:2,20, rep=T)) %>%
  group_by(group) %>%
  summarise(mean=mean(age), sd=sd(age))

除了现有的建议外,您可能还想查看包describe.by中的功能psych

它提供了许多描述性统计数据,包括基于分组变量的平均值和标准差。