我试图找到一个更好的解决方案来同时测试NA
datatable
上的多个列,但没有成功。假设我有一个名为TDT的datatable
,它有x1到x10列,应该测试为非NA。我使用以下语法:
TDT[,natest := ifelse(!is.na(x1) & !is.na(x2) & !is.na(x3) & !is.na(x4) & !is.na(x5) & !is.na(x6) & !is.na(x7) & !is.na(x8) & !is.na(x9) & !is.na(x10), 1, 0)]
这可以写得更简洁吗?
数据:
set.seed(1)
TDT <- data.table(
x1 = round(rnorm(100,0.75,0.3),2),
x2 = round(rnorm(100,0.75,0.3),2),
x3 = round(rnorm(100,0.75,0.3),2),
x4 = round(rnorm(100,0.75,0.3),2),
x5 = round(rnorm(100,0.75,0.3),2),
x6 = round(rnorm(100,0.75,0.3),2),
x7 = round(rnorm(100,0.75,0.3),2),
x8 = round(rnorm(100,0.75,0.3),2),
x9 = c(rep(NA,50),rep(0.1,50)),
x10 = round(rnorm(100,0.75,0.3),2))
答案 0 :(得分:2)
您可以将Reduce
与.SD
一起使用,如下所示:
TDT[, natest := +(!is.na(Reduce("+", .SD)))]
Reduce
获取.SD
提供的变量列表(这是整个data.table)并执行+
操作。然后使用is.na
测试结果,并使用+()
将其转换为二进制变量(0,1存储为整数)。
正如弗兰克的评论所暗示的,这种方法假设列都是数字的。要为此测试选择特定列,您可以使用.SDcols
。
为了使其更加健壮,您可以将data.table的副本复制为逻辑矩阵,将其转换为data.table并执行操作:
TDT[, natest := +(Reduce("+", data.table(!is.na(TDT))) == length(TDT))]
此处,如果仅检查列的子集,则需要调整data.table(!is.na(TDT))
和length(TDT)
。
答案 1 :(得分:2)
这是一个较短的版本
library(data.table)
TDT[, natest := as.numeric(!apply(.SD, 1, anyNA))]
更快的第二个选项
TDT[, natest := as.numeric(!is.na(do.call(pmin, .SD)))]