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

A loop for calculating mean by group and ignore the NA

我想通过组 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 请帮我解决一下。

我试图保留您的代码,但在 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