一个按组计算均值并忽略NA的循环

时间:2019-12-03 12:54:07

标签: r loops dataframe mean

我想通过组groupID计算旧变量的平均值来添加新变量。

df <- data.frame('old'=c('20','21',NA,'30','31'), 'groupID'=c(1,1,1,2,2))

由于这里的人的一些建议,我可以忽略NA(na.rm = TRUE)并获取每个组的平均值

df <- within(df, {new = ave(as.numeric(as.character(old)), groupID, FUN=function(x) mean(x, na.rm=TRUE))}) 

结果不正确

df<-data.frame('old'=c('20','21',NA,'30','31'), 
           'groupID'=c(1,1,1,2,2), 
           'new'=c(20.5,20.5,20.5,30.5,30.5))

现在,我想进一步将其写入循环。

我们在这里的df是:

df <- data.frame('old1'=c('20','21',NA,'30','31'),
               'old2'=c('20','21',NA,'30','35'),
               'old3'=c('20','22',NA,'30','31'),
               'old4'=c('20','25',31,NA,'44'),               
               'groupID'=c(1,1,1,2,2))

我写的循环

for (i in 1:4){ old <- paste0("old", i) df[[paste0("new", i)]] <- with(df, ave(as.numeric(as.character(old)),df$groupID, FUN=function(x)mean(x, na.rm = T)))}  

但是,我的新变量'new1-new4'都充满了NaN 请帮我修复它。

1 个答案:

答案 0 :(得分:1)

我试图保留您的代码,但是在for循环中做了一些小的更改,尤其是对于行old <- paste0("old", i)。现在,我猜您想要的可能是以下内容:

for (i in 1:4) {
  old <- eval(parse(text = paste0("df$old", i))) 
  df[[paste0("new", i)]] <- with(df, ave(as.numeric(as.character(old)),df$groupID, FUN=function(x)mean(x, na.rm = T)))
}

如此

> df
  old1 old2 old3 old4 groupID new1 new2 new3     new4
1   20   20   20   20       1 20.5 20.5 21.0 25.33333
2   21   21   22   25       1 20.5 20.5 21.0 25.33333
3 <NA> <NA> <NA>   31       1 20.5 20.5 21.0 25.33333
4   30   30   30 <NA>       2 30.5 32.5 30.5 44.00000
5   31   35   31   44       2 30.5 32.5 30.5 44.00000