r data.table 为多组列估算缺失值
r data.table impute missing values for multiple set of columns
我想为几组列估算缺失值。这个想法是针对数字变量,我想使用 median 来估算 NA
,对于分类变量,我想使用 mode估算 NA
。我确实搜索了如何为不同的列集分别估算它,但没有找到。
我的数据很大,有很多列,所以我把它放在 data.table 中。由于我不确定如何在 data.table 中执行此操作,我尝试了下面的代码库 R。我已经尝试了下面的代码,但不知何故我弄乱了它似乎的列名标识。
我的数据很大并且有多个变量。我将数值变量存储在向量 var_num 中,我将分类变量存储在向量 var_chr.[=15= 中]
请看下面我的示例代码-
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))
当我尝试 运行 以上时,它给我错误 Error in if (colnames(x) %in% var_num) { : argument is of length zero
请帮助我了解如何更正此问题并实现我的要求。
如评论中所建议,您可以在 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)
}
}
您可能值得也可能不值得花时间为您的两个用例编写一个函数。下面是一个直接(但具体)的解决方案——请注意 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])]
我设法找到了可行的解决方案。关键之一是参考 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 循环 执行所需的插补。
如果有更多更简单和简洁的方法来实现这一点,请告诉我。也许一些应用家庭可以做到这一点。
另一个选项使用 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]])]})
我想为几组列估算缺失值。这个想法是针对数字变量,我想使用 median 来估算 NA
,对于分类变量,我想使用 mode估算 NA
。我确实搜索了如何为不同的列集分别估算它,但没有找到。
我的数据很大,有很多列,所以我把它放在 data.table 中。由于我不确定如何在 data.table 中执行此操作,我尝试了下面的代码库 R。我已经尝试了下面的代码,但不知何故我弄乱了它似乎的列名标识。
我的数据很大并且有多个变量。我将数值变量存储在向量 var_num 中,我将分类变量存储在向量 var_chr.[=15= 中]
请看下面我的示例代码-
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))
当我尝试 运行 以上时,它给我错误 Error in if (colnames(x) %in% var_num) { : argument is of length zero
请帮助我了解如何更正此问题并实现我的要求。
如评论中所建议,您可以在 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)
}
}
您可能值得也可能不值得花时间为您的两个用例编写一个函数。下面是一个直接(但具体)的解决方案——请注意 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])]
我设法找到了可行的解决方案。关键之一是参考 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 循环 执行所需的插补。
如果有更多更简单和简洁的方法来实现这一点,请告诉我。也许一些应用家庭可以做到这一点。
另一个选项使用 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]])]})