R-用固定类别的非零平均值代替零值

时间:2019-03-22 23:39:56

标签: r dataframe replace

我得到了以下形式的数据集

year<-rep(c(1990:1999),each=10) 
age<-rep(50:59, 10)
cat1<-rep(c("A","B","C","D","E"),each=100)
value<-rnorm(10*10*5)
value[c(3,51,100,340,441)]<-0
df<-data.frame(year,age,cat1,value)

  year age  cat1     value
1 1990  50    A -0.7941799
2 1990  51    A  0.1592270
3 1990  52    A  0.0000000
4 1990  53    A  1.9222384  
5 1990  54    A  0.3922259
6 1990  55    A -1.2671957

我现在想用相应年份和年龄的“值”非零条目的“ cat1”列上的平均值替换“值”列中的任何零。例如,对于1990年(52岁),cat1 = A的enty为零,应该用该特定年份和年龄的其余类别的非零条目的平均值代替。 就像我们

df[df$year==1990 & df$age==52,]
    year age  cat1     value
3   1990  52    A  0.0000000
103 1990  52    B -1.1325446
203 1990  52    C -1.6136773  
303 1990  52    D  0.5724360
403 1990  52    E  0.2795241

我们将条目0替换为

sum(df[df$year==1990 & df$age==52,4])/4
[1] -0.4735654

一般来说,有没有一种好方法?

2 个答案:

答案 0 :(得分:1)

library(data.table)
setDT(df)[value==0, value := NA,]
df[, value := replace(value, is.na(value), mean(value, na.rm = TRUE)) , by = .(year, age)]

答案 1 :(得分:0)

也许可以将99.9%的表操作分解为基本的快速优化对象:拆分,串联(如果是数字,则是求和,乘法等),过滤,排序,联接。

dplyr的left_join在这里,是您的理想之选。 只需创建另一个从零开始过滤并汇总到的数据框即可,并进行适当的分组。然后用新加入的列中的值替换零。