data.table 将 NA 替换为多列的均值和 id
data.table replace NA with mean for multiple columns and by id
如果我有以下 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]
您可以对每一列使用 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
要评估只有列名的列,我们可以使用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
如果我有以下 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]
您可以对每一列使用 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
要评估只有列名的列,我们可以使用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