给出以下数据格式:
c1 c2 c3
A B 100
A B 200
A C 0
A C 0
D E 550
D E 700
D F 100
D F 0
我想在同一个A和B的组中得到c3的平均值。使用R的aggregate
函数:
aggregate(c3~c1+c2, data=myData, FUN=mean)
我得到了正确的子集均值表:
A B 150
A C 0
D E 625
D F 50
然而,如果有值和零,我想排除案例的平均计算。这就是第一个代码的最后两行;
D F 100
D F 0
应评估为:
D F 100
有没有办法修改aggregate
功能?或者是否有一种优雅的方式来预先处理我的数据?
答案 0 :(得分:2)
也许您可以传递一个自定义函数来搜索您提到的条件(x包括零和非零值),如果满足,则返回第一种情况下非零值的平均值,否则您计算标准意味着一如既往。
#prepare data
df <- data.frame(c1=c("A","A","A","A","D","D","D","D"),
c2= c("B","B","C","C","E","E","F","F"),
c3= c(100,200,0,0,550,700,100,0))
#aggregate
aggregate(c3~c1+c2, data=df, FUN=(function(x){ifelse(sum(x==0)>0 & sum(x !=0) >0, mean(x[x>0]), mean(x))}))
c1 c2 c3
1 A B 150
2 A C 0
3 D E 625
4 D F 100
答案 1 :(得分:2)
我们可以使用data.table
library(data.table)
setDT(myData)[, .(c3 = if(!all(c3==0)) mean(c3[c3!=0]) else 0), .(c1, c2)]
# c1 c2 c3
#1: A B 150
#2: A C 0
#3: D E 625
#4: D F 100
答案 2 :(得分:2)
使用aggregate
的另一种选择。内部函数通过索引工作,并选择是否将0值转换为NA并使用na.rm=TRUE
计算均值或根据所有值是否为0返回0.
aggregate(c3 ~ c1 + c2, dat,
FUN=function(x) c(mean(x * NA^(!x), na.rm=TRUE), 0)[all(x == 0) + 1L])
c1 c2 c3
1 A B 150
2 A C 0
3 D E 625
4 D F 100