如何移除data.table中列a的向量含嵌套NA的行?
解决data.table中移除列表列含NA的行的问题
你的需求是移除dt中列a的向量里包含任意NA的行(仅保留向量全为非NA的行),以下是可行的解决方法:
方法1:用sapply结合anyNA
dt[!sapply(a, anyNA)]
原理:
sapply(a, anyNA)会遍历列a的每个列表元素(即每个向量),判断该向量中是否存在NA,返回一个与行数等长的逻辑向量(存在NA则为TRUE,否则为FALSE)。- 前面加
!取反,得到需要保留的行(向量中无NA的行),直接用于筛选data.table即可。
方法2:判断向量全为非NA的写法
如果你倾向于用类似你第三种尝试的思路,也可以这样写:
dt[dt[, sapply(a, function(x) all(!is.na(x)))]] # 或者用Reduce实现相同逻辑: dt[dt[, sapply(a, function(x) Reduce(`&`, !is.na(x)))]]
原理:
- 对每个向量
x,!is.na(x)生成该向量每个元素是否非NA的逻辑向量,all()或Reduce(&, ...)会判断这个逻辑向量是否全为TRUE(即向量无任何NA),返回的逻辑向量用于筛选目标行。
你的三种尝试失败的原因:
dt[!is.na(a)]:is.na(a)判断的是整个列表元素是否为NA,而非元素内部向量里的NA。你的a列中没有元素本身是NA,所以这个筛选完全不起作用。dt[!is.na(unlist(a))]:unlist(a)会把所有向量的元素展开成一个长向量,长度远大于dt的行数,用这个逻辑向量筛选行时,因长度不匹配会报错或得到错误结果。dt[dt[,!Reduce(&, lapply(a, is.na))]]:lapply(a, is.na)得到每个向量的NA判断逻辑向量,Reduce(&, ...)是把每个向量里的逻辑值按位与,仅当向量全为NA时才返回TRUE,取反后保留的是「不是全NA」的行,和你需要的「完全没有NA」的行逻辑完全相反,且这种写法也无法正确处理不同长度的向量。
内容的提问来源于stack exchange,提问作者Fabio Correa
相关产品推荐
相关产品推荐

