如果我有以下data.table:
dat <- data.table("id"=c(1,1,1,1,2,2,2,2), "var1"=c(NA,1,2,2,1,1,2,2),
"var2"=c(4,4,4,4,5,5,NA,4), "var3"=c(4,4,4,NA,5,5,5,4))
id var1 var2 var3
1: 1 NA 4 4
2: 1 1 4 4
3: 1 2 4 4
4: 1 2 4 NA
5: 2 1 5 5
6: 2 1 5 5
7: 2 2 NA 5
8: 2 2 4 4
如何用id中每列的平均值替换缺失值?在我的实际数据中,我有很多变量,对于我想要替换的变量,所以如何以一般方式完成,例如它不能替换为var3而只替换为var1和var2?:
tomean=c("var1", "var2")
我试过这样的事情,但我还没有找到解决办法:
dat[, (tomean) := mean(tomean, na.rm=TRUE), by=id, .SDcols = tomean]
答案 0 :(得分:9)
要评估仅包含列名称的列,我们可以使用get()
。我们需要lapply()
来对多个列执行此操作。
## determine the column names that contain NA values
nm <- names(dat)[colSums(is.na(dat)) != 0]
## replace with the mean - by 'id'
dat[, (nm) := lapply(nm, function(x) {
x <- get(x)
x[is.na(x)] <- mean(x, na.rm = TRUE)
x
}), by = id]
提供更新后的dat
id var1 var2 var3
1: 1 1.666667 4.000000 4
2: 1 1.000000 4.000000 4
3: 1 2.000000 4.000000 4
4: 1 2.000000 4.000000 3
5: 2 1.000000 5.000000 5
6: 2 1.000000 5.000000 5
7: 2 2.000000 4.666667 5
8: 2 2.000000 4.000000 4
更新:对于您更新的问题,为避免在包含NA的所有列上运行此问题,请不要使用nm
。只需使用您自己的向量tomean
。
tomean <- c("var1", "var2")
dat[, (tomean) := lapply(tomean, function(x) {
x <- get(x)
x[is.na(x)] <- mean(x, na.rm = TRUE)
x
}), by = id]
,这给了
id var1 var2 var3
1: 1 1.666667 4.000000 4
2: 1 1.000000 4.000000 4
3: 1 2.000000 4.000000 4
4: 1 2.000000 4.000000 NA
5: 2 1.000000 5.000000 5
6: 2 1.000000 5.000000 5
7: 2 2.000000 4.666667 5
8: 2 2.000000 4.000000 4
答案 1 :(得分:1)
您可以在每列上使用apply
功能,以便:
dat[,as.data.table(apply(.SD, 2, function(x) {x[is.na(x)] <- mean(x, na.rm=T); x})),by=id]
id var1 var2 var3
1: 1 1.666667 4.000000 4
2: 1 1.000000 4.000000 4
3: 1 2.000000 4.000000 4
4: 1 2.000000 4.000000 3
5: 2 1.000000 5.000000 5
6: 2 1.000000 5.000000 5
7: 2 2.000000 4.666667 5
8: 2 2.000000 4.000000 4