【问题标题】:handling 'wrong' entries and NAs in a data.table substituting them with entries from other table处理 data.table 中的“错误”条目和 NA,用其他表中的条目替换它们
【发布时间】:2015-01-01 20:07:02
【问题描述】:

我在使用闪亮和handsontable.js 的更广泛应用程序的上下文中使用 data.table。这是应用程序这部分的流程:

  1. 我在浏览器上发布了一个 data.table,其中包含使用 handsontable & shiny 的数字列。这是在屏幕上呈现的。
  2. 用户更改值,每次发生这种情况时都会返回一个新的 data.table 和数据。

问题在于错误管理,特别是如果用户不小心键入了一个字符。

我的目标是纠正用户的错误,将输入字符的单个单元格值替换为原始副本中的值(仅此单元格,因为其他单元格可能包含要在应用程序后期保存的有效更改) .

遗憾的是,我无法找到解决此问题的有效方法。这是我的代码和可重现的示例:

# I generate a sample datatable
originTable = data.table( Cat = LETTERS[1:5],
Jan=1:5,
Feb=sample(1:5),
Mar=sample(1:5),
Apr=sample(1:5),
May=sample(1:5))

# I take a full copy & to simulate the effect of a character key in by mistake I convert
# the entire column to character
dt_ <- copy(originTable)
dt_[,Jan := as.character(Jan)]

# "q" entered by mistake by the user - 
dt_[[5,2]] <- "q"

# This is what I get back:
   Cat Jan Feb Mar Apr May
1:   A   1   1   2   4   4
2:   B   2   5   4   2   2
3:   C   3   4   3   1   5
4:   D   4   3   5   5   1
5:   E   q   2   1   3   3

现在我的代码尝试解决这个问题:

valCols <- month.abb[1:5]
for (j in  valCols)
      set(dt_,  
        i = NULL,
        j = j, 
        value= as.numeric(as.character(dt_[[j]])))

这给了我一个带有 NA 值的 data.table(代替错误输入的字符 - 在我忽略的位置)。

为了替换我使用以下代码的值

for (j in  valCols)
   set(dt_,  
    i = which(is.na(dt_[[j]])),
    j = j, 
    value= as.numeric(originTable[[j]]))

但它不起作用:它找到了正确的列,但忽略了i 值并复制了originTable[1,j] 中包含的值而不是originTable[i,j]。在示例中 dt_[5,2] 将得到 1(定位为 originTable[1,2] 而不是 5。

换句话说,我希望看到as.numeric(originTable[[j]])i(隐式)和j(显式)子集化。 公平地说,警告告诉我发生了什么:

Warning message:
In set(dt_, i = which(is.na(dt_[[j]])), j = j, value = as.numeric(originTable[[j]])) :
  Supplied 5 items to be assigned to 1 items of column 'Jan' (4 unused)

但我的问题仍未解决。

我已经阅读了无数明显相似的 SO 帖子,但遗憾的是无济于事(可能是因为 NA 处理在最近的版本中有所发展,而旧的答案不再完全反映最佳实践)。同样可以接受非基于 NA 的解决方案。谢谢

【问题讨论】:

  • 我建议您仅使用 一个可重现的小示例 以及您的代码来隔离您遇到问题的 data.table 部分(没有所有其他细节)不工作/错误是什么等等。
  • @Arun 添加了一个可重现的小示例等。我希望它更清楚。谢谢 E
  • @Arun & @Matt_Dowle 我是 data.table 的粉丝。虽然我对@eddi 的回答感到满意,但我相信如果 data.table 在未来的某个时候允许(显式) i, j 语法会很棒。例如,对于上面的示例set(dt_,i = which(is.na(dt_[[j]])), j = j, value= as.numeric(originTable[[i,j]])),它当前给出了错误。
  • @Enzo data.table 语法确实允许这样做。您在 OP 中的表达式中的问题是您尝试将整个向量分配给单个单元格。如果您在循环中修改了..., value = as.numeric(originTable[[j]][which(is.na(dt_[[j]]))]),它可以工作

标签: r data.table na


【解决方案1】:

尝试以下方法:

# use your criteria to determine what the incorrect values are in each column
wrongs = lapply(dt_[, !"Cat"], function(x) which(is.na(as.numeric(x))))

# now substitute
for (n in names(wrongs)) dt_[wrongs[[n]], (n) := originTable[[n]][wrongs[[n]]]]

dt_
#   Cat Jan Feb Mar Apr May
#1:   A   1   2   5   2   4
#2:   B   2   4   3   4   5
#3:   C   3   3   2   5   2
#4:   D   4   1   1   1   1
#5:   E   5   5   4   3   3

【讨论】:

    猜你喜欢
    • 2016-08-26
    • 1970-01-01
    • 2021-10-22
    • 2012-02-04
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    相关资源
    最近更新 更多