Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
r data.table为多组列输入缺失值_R_Function_Data.table_Missing Data_Imputation - Fatal编程技术网

r data.table为多组列输入缺失值

r data.table为多组列输入缺失值,r,function,data.table,missing-data,imputation,R,Function,Data.table,Missing Data,Imputation,我想为几组列计算缺少的值。对于数值变量,我想使用中位数来插补NA,对于分类变量,我想使用模式来插补NA。我确实搜索了如何对不同的列分别进行插补,但没有找到 我的数据很大,有很多列,所以我把它放在data.table中。由于我不确定如何在data.table中执行此操作,所以我尝试在代码基R下方执行此操作。我尝试在代码下方执行此操作,但不知何故,我似乎弄乱了列名标识 我的数据很大,有多个变量。我在vectorvar\u num中存储数值变量,在vectorvar\u chr中存储分类变量 请参阅下

我想为几组列计算缺少的值。对于数值变量,我想使用中位数来插补
NA
,对于分类变量,我想使用模式来插补
NA
。我确实搜索了如何对不同的列分别进行插补,但没有找到

我的数据很大,有很多列,所以我把它放在data.table中。由于我不确定如何在data.table中执行此操作,所以我尝试在代码基R下方执行此操作。我尝试在代码下方执行此操作,但不知何故,我似乎弄乱了列名标识

我的数据很大,有多个变量。我在vectorvar\u num中存储数值变量,在vectorvar\u chr中存储分类变量

请参阅下面的示例代码-

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))
库(data.table)
种子集(1200)

id正如注释中所建议的,您可以在data.table中为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)
    }
}
for(名称中的k(df1)){
如果(k%在%var\u num中){
#用中位数输入数值变量

med正如注释中所建议的,您可以在data.table中对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)
    }
}
for(名称中的k(df1)){
如果(k%在%var\u num中){
#用中位数输入数值变量

med为您的两个用例编写一个函数可能值得,也可能不值得。下面是一个直接(但具体)的解决方案——请注意,
模式
通过阅读
?模式
,可能不会像您预期的那样运行

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])]
库(data.table)
种子集(1200)

df1为您的两个用例编写一个函数可能值得,也可能不值得。下面是一个直接(但具体)的解决方案——请注意,
模式
通过阅读
?模式
,可能不会像您预期的那样运行

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])]
库(data.table)
种子集(1200)

df1我设法找到了一个有效的解决方案。其中一个关键问题是引用var_numvar_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])))
  }
}

df1我设法得到了一个有效的解决方案。其中一个关键问题是引用var_numvar_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])))
  }
}

df1使用
lappy的另一个选项

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]])]})
lappy(c(var_num,var_chr),函数(x){

imp.fun使用
lappy的另一个选项

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]])]})
lappy(c(var_num,var_chr),函数(x){

如果你使用的是<代码>数据。表< /代码>,你应该考虑利用它的功能,如引用更新,使用<代码>:= <代码/ >附件,或者在这种情况下可能更适合,<代码> < /COD> >代码> SET>代码>重复几个列。如果你使用<代码>数据。表< /Cord>你应该考虑利用它。对于它的功能,例如使用
:=
赋值进行引用更新,或者在本例中可能更适合使用
for
+
设置
以迭代多个列。感谢您的回答。我想引用var_num和var_chr中指定的变量……您的解决方案将对所有列进行插补。但是是的,它是我会是一个很好的参考。这是我不能马上想出的一般解决方案;)请注意,对于OP,使用这种方法,
df1
的“type”列需要更改为一个因子或字符来计算模式,而不是中值(因为它是一个数字向量,但需要模式)@user1412我以前将其变得更通用,这样您就不需要硬编码列名,只需更新答案。@YOLO谢谢!!谢谢您的回答。我想引用var_num和var_chr中指定的变量…..您的解决方案将对所有列进行插补。但是,是的,这将是一个很好的参考。下面是General所有解决方案我无法立即想出;)请注意,对于OP,使用此方法,
df1
的“type”列需要更改为因子或字符,以计算模式而不是中值(因为它是一个数字向量,但需要模式)@user1412我以前将其变得更通用,这样您就不需要硬编码列名,只需更新答案即可。@YOLO谢谢!!谢谢您的回答。是的,我知道在R中使用不同的模式,并且使用名称的组合(这(表…见我的答案。正如你所提到的,这将是一个漫长的过程,因为有很多变量…谢谢你的回答。是的,我得到的模式在R中是不同的,使用名称的组合(其中(表…见我的答案。正如你所提到的,这将是一个漫长的过程,因为有很多变量…代码没有运行,但有类似的
imp=df1[,c(lappy(.SD[,…var_num],media,na.rm=TRUE),lappy(.SD[,…var_chr],getMode)];for(k in c(var_num,var_chr))df1[is.na(get(k)),(k):=imp[[k]]
(从caw的答案中借用的getMode)代码没有运行,但有类似的
imp=df1[,c(lappy(.SD[,var_num],median,na.rm=TRUE),lappy(.SD[,…var_chr],getMode)];for(k in c(var_num,var_chr))df1[is.na(get(k)),(k):=imp[[k]][/code>(从caw的答案中借用的getMode)