删除向量元素包含嵌套 NA 的 data.table 行

Fab*_*rea 3 r data.table

我需要从 data.table 中删除列包含向量中嵌套的a任何行:NA

library(data.table)

a = list(as.numeric(c(NA,NA)), 2,as.numeric(c(3, NA)), c(4,5) )
b <- 11:14

dt <- data.table(a,b)
Run Code Online (Sandbox Code Playgroud)

因此,应删除第 1 行和第 3 行。

我尝试了三种解决方案但没有成功:

dt1 <- dt[!is.na(a)] 
dt2 <- dt[!is.na(unlist(a))]
dt3 <- dt[dt[,!Reduce(`&`, lapply(a, is.na))]]
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?谢谢。

lan*_*ang 5

您可以执行以下操作:

dt[sapply(dt$a, \(l) !any(is.na(l)))]
Run Code Online (Sandbox Code Playgroud)

此替代方案也有效,但您会收到警告

dt[sapply(dt$a, all)]
Run Code Online (Sandbox Code Playgroud)

更好的方法(感谢 r2evans,请参阅评论)

dt[!sapply(a,anyNA)]
Run Code Online (Sandbox Code Playgroud)

输出:

     a  b
1:   2 12
2: 4,5 14
Run Code Online (Sandbox Code Playgroud)

您可能更喜欢的第三个选项:您可以将该功能移至一个单独的辅助函数,该函数接收列表列表 ( nl),并返回长度等于 的布尔向量length(nl),然后应用该函数,如下所示。在这个例子中,我明确地调用unlist()了结果,lapply()而不是sapply()让我这样做,但我也可以使用sapply()

f <- \(nl) unlist(lapply(nl,\(l) !any(is.na(l))))

dt[f(a)]
Run Code Online (Sandbox Code Playgroud)

  • `any(is.na(.))` 可以简化为 `anyNA(.)`,这意味着您的第一个表达式可以简化为 `dt[!sapply(a, anyNA),]` 以获得相同的结果(并且更好的代码高尔夫)。(由于这是“data.table”,因此不需要“dt$”。) (3认同)