我想为几组列估算缺失值。我的想法是针对要使用中位数的数字变量来归纳NA
,对于归类变量,我要使用 mode 来归纳{{1 }}。我确实搜索了如何针对不同的列集分别进行插补,但没有找到。
我的数据很大,有很多列,所以我将其保存在 data.table 中。由于我不确定如何在data.table中执行此操作,因此我尝试在代码库R下进行尝试。我曾尝试在下面的代码中进行尝试,但是不知何故,我似乎弄乱了列名的标识。
我的数据很大,并且有多个变量。我将数值变量存储在向量 var_num 中,并将类别变量存储在向量 var_chr 中。
请在下面查看我的示例代码-
NA
当我尝试运行上面的命令时,它给我错误library(data.table)
set.seed(1200)
id <- 1:100
bills <- sample(c(1:20,NA),100,replace = T)
nos <- sample(c(1:80,NA),100,replace = T)
stru <- sample(c("A","B","C","D",NA),100,replace = T)
type <- sample(c(1:7,NA),100,replace = T)
value <- sample(c(100:1000,NA),100,replace = T)
df1 <- as.data.table(data.frame(id,bills,nos,stru,type,value))
class(df1)
var_num <- c("bills","nos","value")
var_chr <- c("stru","type")
impute <- function(x){
#print(x)
if(colnames(x) %in% var_num){
x[is.na(x)] = median(x,na.rm = T)
} else if (colnames(x) %in% var_chr){
x[is.na(x)] = mode(x)
} else {
x #if not part of var_num and var_chr then nothing needs to be done and return the original value
}
return(x)
}
df1_imp_med <- data.frame(apply(df1,2,impute))
请帮助我了解如何解决此问题并达到要求。
答案 0 :(得分:3)
如注释中所建议,您可以在data.table中使用for-set
组合以更快地进行插补:
for(k in names(df1)){
if(k %in% var_num){
# impute numeric variables with median
med <- median(df1[[k]],na.rm = T)
set(x = df1, which(is.na(df1[[k]])), k, med)
} else if(k %in% var_char){
## impute categorical variables with mode
mode <- names(which.max(table(df1[[k]])))
set(x = df1, which(is.na(df1[[k]])), k, mode)
}
}
答案 1 :(得分:1)
为您的两个用例编写一个功能可能不值得,您可能不值得花时间。下面是一个直接的(但具体的)解决方案-请注意,mode
的行为可能不符合您的预期,方法是阅读?mode
。
library(data.table)
set.seed(1200)
df1 <- data.table(
id = 1:100,
bills = sample(c(1:20,NA),100,replace = T),
nos = sample(c(1:80,NA),100,replace = T),
stru = sample(c("A","B","C","D",NA),100,replace = T),
type = sample(c(as.character(1:7),NA),100,replace = T),
value = sample(c(100:1000,NA),100,replace = T)
)
# Function to calculate the most frequent object in a vector:
getMode <- function(myvector) {
mytable <- table(myvector)
return(names(mytable)[which.max(mytable)])
}
# replace na values by reference, with `:=`
df1[is.na(bills), bills := median(df1[,bills], na.rm=T)]
df1[is.na(nos), nos := median(df1[,nos], na.rm=T)]
df1[is.na(value), value := median(df1[,value], na.rm=T)]
df1[is.na(stru), stru := getMode(df1[,stru])]
df1[is.na(type), type := getMode(df1[,type])]
答案 2 :(得分:0)
我设法找到了可行的解决方案。关键之一是要引用 var_num 和 var_chr 中指定的变量,以进行数字和类别插补。这些向量中未指定的变量无需插补。
我面临的挑战是在函数中引用它们。我放弃了编写函数的想法,并设法编写了 for循环,如下所示-
df1 <- as.data.frame(df1)
for (var in 1:ncol(df1)) {
if (names(df1[var]) %in% var_num) {
df1[is.na(df1[,var]),var] <- median(df1[,var], na.rm = TRUE)
} else if (names(df1[var]) %in% var_chr) {
df1[is.na(df1[,var]),var] <- names(which.max(table(df1[,var])))
}
}
此 for循环执行所需的估算。
如果还有更多更简单和简洁的方式来实现此目标,请告诉我。也许有些应征家庭可以解决这个问题。
答案 3 :(得分:0)
另一个使用lapply
lapply(c(var_num, var_chr), function(x){
imp.fun <- ifelse(x %in% var_num
, function(x) median(x, na.rm = T)
, function(x) names(which.max(table(x))))
df1[is.na(df1[[x]]), (x) := imp.fun(df1[[x]])]})