【问题标题】:Mean imputation issue with data.tabledata.table 的平均插补问题
【发布时间】:2017-05-31 13:33:46
【问题描述】:

尝试使用此循环在所有数字行中估算缺失值:

for(i in 1:ncol(df)){
  if (is.numeric(df[,i])){
    df[is.na(df[,i]), i] <- mean(df[,i], na.rm = TRUE)
  }
}

如果未附加 data.table 包,则上面的代码可以正常工作。一旦我附加了 data.table 包,行为就会改变,它会向我显示错误:

Error in `[.data.table`(df, , i) : 
  j (the 2nd argument inside [...]) is a single symbol but column name 'i' 
is not found. Perhaps you intended DT[,..i] or DT[,i,with=FALSE]. This 
difference to data.frame is deliberate and explained in FAQ 1.1.

我到处尝试了“..i”和“with=FALSE”,但没有成功。实际上它甚至没有通过第一个 is.numeric 条件。

【问题讨论】:

标签: r data.table


【解决方案1】:

data.table 语法在这种情况下略有不同。你可以这样做:

num_cols <- names(df)[sapply(df, is.numeric)]
for(col in num_cols) {
  set(df, i = which(is.na(df[[col]])), j = col, value = mean(df[[col]], na.rm=TRUE))
}

或者,如果您想继续使用现有循环,您可以使用

将数据转回data.frame
setDF(df)

【讨论】:

  • 工作得很好。谢谢!
  • set 在 data.table 或 data.frame 上工作,fwiw,所以他们可以setDF 然后仍然使用你的(更有效的)循环。
【解决方案2】:

这个问题的另一个答案是我在大规模地解决类似问题时想出的。有人可能对使用 [.data.table 方法避免 for 循环感兴趣。

DF[i, j, by, on, ...]

首先我们将创建一个可以执行插补的函数

 impute_na <- function(x, val = mean, ...){
   if(!is.numeric(x))return(x)
   na <- is.na(x)
   if(is.function(val))
     val <- val(x[!na])
   if(!is.numeric(val)||length(val)>1)
     stop("'val' needs to be either a function or a single numeric value!")
   x[na] <- val
   x
 }

要对数据框执行插补,可以在 data.table 环境中创建和评估表达式,但为了简单起见,我们将使用 &lt;- 覆盖

DF <- DF[, lapply(.SD, impute_na)]

这将估算所有数字列的平均值,并保持所有非数字列不变。如果我们希望估算另一个值(例如... 42 或其他值),也许我们有一些分组变量,我们只希望在此上计算的平均值也可以包含在

DF <- DF[, lapply(.SD, impute_na, val = 42)]
DF <- DF[, lapply(.SD, impute_NA), by = group]

这将分别估算 42 和组内平均值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 2017-05-04
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2017-10-04
    • 1970-01-01
    相关资源
    最近更新 更多