R 处理data.table中的“错误”条目和NAs将它们替换为其他表中的条目

R 处理data.table中的“错误”条目和NAs将它们替换为其他表中的条目,r,data.table,na,R,Data.table,Na,我在更广泛的应用程序环境中使用data.table,使用的是shiny和。这是应用程序此部分的流程: 我使用handsontable和shinny在浏览器上发布带有数字列的data.table。这将在屏幕上呈现。 用户更改值,每次都会返回一个新的data.table和数据。 问题在于错误管理,特别是当用户意外键入字符时 我的目标是纠正用户的错误,将输入字符的单个单元格值替换为原始副本中的值仅此单元格,因为其他单元格可能包含有效更改,将在应用程序的稍后阶段保存 遗憾的是,我无法找到一个有效解决这个

我在更广泛的应用程序环境中使用data.table,使用的是shiny和。这是应用程序此部分的流程:

我使用handsontable和shinny在浏览器上发布带有数字列的data.table。这将在屏幕上呈现。 用户更改值,每次都会返回一个新的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
但它不起作用:它找到正确的列,但忽略i值,并复制originTable[1,j]而不是originTable[i,j]中包含的值。在示例中,dt_5,2]将1定位为原始表[1,2],而不是5

换言之,我希望看到I隐式地和j显式地将as.numericorgintable[[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处理在最近的版本中有所发展,旧的答案不再完全反映最佳实践。此外,非钠基解决方案也同样可以接受。谢谢

请尝试以下操作:

# 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

我建议您只隔离数据。表格部分,您有问题,没有所有其他细节,使用一个小的可复制示例,以及您的哪些代码不起作用/错误是什么等。@Arun添加了一个小的可复制示例等。我希望它更清晰。谢谢E@Arun&@Matt_Dowle我是一个数据表迷。虽然我对@eddi的答案感到满意,但我相信如果data.table在将来的某个时候允许显式的I,j语法,那就太好了。例如,对于上面的示例,setdt_u3;,i=whichis.nadt_3;[[j]],j=j,value=as.numericorgintable[[i,j]],它当前给出了错误。@Enzo data.table语法允许这样做。OP中表达式的问题在于,您试图将整个向量指定给单个单元格。如果您在循环中修改了…,value=as.numericoriginTable[[j]][whichis.nadt_[[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)
# 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