R中的id变量进行简单聚合

时间:2015-06-01 21:58:23

标签: r aggregate

我遇到了聚合函数的问题。我的data.frame看起来像这样:

**Region    Sex   SNI      value**
orebro      Man     0       497
orebro      Man     0        1
orebro      Man     1       120
referens    Man     96      3045
referens    Man     96       41
referens    Woman   0       2061
referens    Woman   0       2450

但我希望它看起来像这样:

**  Region      Sex   SNI      value**
    orebro      Man     0       498
    orebro      Man     1       120
    referens    Man     96      3086
    referens    Woman   0       4106

所以我想合并所有具有相同的Region,Sex和SNI值的观察结果。我试过了:

mydata2 <-aggregate(mydata, by=list(mydata$Region, mydata$Sex, mydata$SNI), 
                FUN=mean, na.rm=TRUE)

但是我收到了警告信息:

50: In mean.default(X[[50L]], ...) :
  argument is not numeric or logical: returning NA

结果数据框已损坏。我究竟做错了什么?我想这与尝试合并字符串有关?

1 个答案:

答案 0 :(得分:2)

如果aggregate()被赋予data.frame作为其第一个参数,那么它会尝试使用FUN()分别聚合该data.frame的每一列。这意味着它将通过mean()运行您的region,sex和sni列,这是不正确的。相反,您需要在第一个参数中仅传递值列,并且需要注意不要提取向量(而不是保留data.frame结构),否则您将丢失列名。

其次,您的第二个参数中的列表是未命名的,这意味着结果将丢失分组列的列名。你可以通过明确地命名它们来解决这个问题,即list(Region=mydata$Region, ... ),但是有一种更好的方法,就是从data.frame中索引出分组列。这是有效的,因为data.frames是内部列表。

以下是使用2D索引的工作原理:

df <- data.frame(region=c('orebro','orebro','orebro','referens','referens','referens','referens'), sex=c('Man','Man','Man','Man','Man','Woman','Woman'), sni=c(0,0,1,96,96,0,0), value=c(497,1,120,3045,41,2061,2450) );
aggregate(df[,'value',drop=F],by=df[,c('region','sex','sni')],sum,na.rm=T);
##     region   sex sni value
## 1   orebro   Man   0   498
## 2 referens Woman   0  4511
## 3   orebro   Man   1   120
## 4 referens   Man  96  3086

或者,使用列表索引:

aggregate(df['value'],by=df[c('region','sex','sni')],sum,na.rm=T);
##     region   sex sni value
## 1   orebro   Man   0   498
## 2 referens Woman   0  4511
## 3   orebro   Man   1   120
## 4 referens   Man  96  3086

现在,实际上有一种更好的更好的方式,即使用aggregate()的公式接口:

aggregate(value~region+sex+sni,df,sum,na.rm=T);
##     region   sex sni value
## 1   orebro   Man   0   498
## 2 referens Woman   0  4511
## 3   orebro   Man   1   120
## 4 referens   Man  96  3086

另外,您可能已经注意到我使用了sum()而不是mean()。我这样做是因为你的预期输出有和而不是平均值,尽管你的referens / Woman / 0值不正确。