数据表中的多列条件

时间:2017-03-09 17:17:19

标签: r data.table

我试图找到一个更好的解决方案来同时测试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))

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)))]