我的数据类似于:
dt <-data.table(V1=c(-1,NA,10),V2=c(-2,3,15),V3=c(NA,5,20),V4=c(NA,NA,NA),V5=c(-3,7,NA),
avg=c(-2,5,15),stdev=c(.82,1.63,4.08))
看起来像:
V1 V2 V3 V4 V5 avg stdev
1 -1 -2 NA NA -3 -2 0.82
2 NA 3 5 NA 7 5 1.63
3 10 15 20 NA NA 15 4.08
我想用正态分布的随机数替换每个NA,使用avg
列的平均值和stdev
列的标准偏差。例如,在第1行中,我想要使用mean = -2和sd = 0.82计算两个随机数(以替换V3
中的NA,V4
)。在第2行中,我想要使用mean = 5和sd = 1.63等计算两个随机数(以替换V1
中的NA,V4
)等。所有行的逻辑相同。我试过这个并没有按预期工作:
for (col in colnames(dt)) dt[is.na(get(col)), (col) := rnorm(1,mean=(avg),sd=(stdev))]
我欢迎任何想法。感谢。
答案 0 :(得分:2)
你非常接近。
library(data.table)
dt <-data.table(V1=c(-1,NA,10),V2=c(-2,3,15),V3=c(NA,5,20),V4=c(NA,NA,NA),V5=c(-3,7,NA),
avg=c(-2,5,15),stdev=c(.82,1.63,4.08))
# change V4 to numeric, otherwise is logical
dt[, V4 := as.numeric(V4)]
set.seed(1234)
for (col in names(dt)[1:5]){
# rnorm() is more annoying than expected, n = 1 cannot recycle
dt[is.na(get(col)), (col) := as.numeric(rnorm(rep(1, sum(is.na(get(col)))), avg, stdev))]
}
# V1 V2 V3 V4 V5 avg stdev
# 1: -1.000000 -2 -1.772508 -1.110758 -3.00000 -2 0.82
# 2: 3.032483 3 5.000000 1.176513 7.00000 5 1.63
# 3: 10.000000 15 20.000000 16.750829 17.06471 15 4.08
答案 1 :(得分:1)
我将假设avg
和stdev
列没有任何特殊之处,它们只是行方式和标准偏差。
首先是助手插补功能
impute <- function(x) {
avg <- mean(x, na.rm = TRUE)
stdev <- sd(x, na.rm = TRUE)
indices <- which(is.na(x))
x[indices] <- rnorm(length(indices), avg, stdev)
x
}
接下来删除avg
和stdev
列。
no_avg <- dt[, !(colnames(dt) %in% c("avg", "stdev"))]
然后按行impute
行。 data.table
和t
只是让我们回到原来的格式。
data.table(t(apply(no_avg, 1, impute)))