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
...
今天学到的方法是:
plyr包中的ddply函数如下:
dt <- data.frame(age=rchisq(20,10),group=sample(1:2,20,rep=T))
ddply(dt,~group,summarise,mean=mean(age),sd=sd(age))
~group是指可以使用levels(factor(data$group))函数得到的类别,age即为想得到的按组的处理目标。还有一种方法,今天来不及实验,先放到下面:
Here is the plyr one line variant using ddply:
dt <- data.frame(age=rchisq(20,10),group=sample(1:2,20,rep=T))
ddply(dt,~group,summarise,mean=mean(age),sd=sd(age))
Here is another one line variant using new package data.table.
dtf <- data.frame(age=rchisq(100000,10),group=factor(sample(1:10,100000,rep=T)))
dt <- data.table(dt)
dt[,list(mean=mean(age),sd=sd(age)),by=group]
This one is faster, though this is noticeable only on table with 100k rows. Timings on my Macbook Pro with 2.53 Ghz Core 2 Duo processor and R 2.11.1:
> 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
Further savings are possible if we use 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