我遇到了聚合函数的问题。我的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
结果数据框已损坏。我究竟做错了什么?我想这与尝试合并字符串有关?
答案 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值不正确。