如何用dplyr过滤指定列NA行?反向过滤无结果求解决
问题解决:筛选指定列全为NA的行无结果的原因及方案
示例数据
data <- structure(list(sample_id = c("2023.01.12_2", "2023.01.12_27", "2023.01.12_27", "2023.01.12_3", "2023.01.12_27", "2023.01.12_27", "2023.01.12_4", "2023.01.12_27", "2023.01.12_27", "2023.01.12_5" ), group = c("Unedited", "Rob", "Rob", "Partial_promoter", "Rob", "Rob", "Promoter_and_ATG", "Rob", "Rob", "ATG"), day = c(6, NA, NA, 6, NA, NA, 6, NA, NA, 6), x = c(114.243333333333, 115.036666666667, 115.073333333333, 114.41, 116.11, 116.163333333333, 113.426666666667, 116.15, 117.253333333333, 113.46)), row.names = c(NA, -10L), class = "data.frame") cols <- c("group", "day")
问题分析
你当前使用的反向筛选代码:
data %>% filter(across(.cols = cols, .fns = ~ is.na(.x)))
无结果的核心原因是:你的示例数据中group列没有任何NA值,而across搭配该逻辑要求cols指定的所有列(group和day)都必须为NA,自然没有符合条件的行,所以返回空结果。
针对性解决方案
根据你的实际需求,分两种情况处理:
情况1:确实需要保留「指定列全部为NA」的行
如果你的真实数据中存在满足条件的行,原代码逻辑是正确的,也可以用更清晰的写法强化逻辑:
data %>% filter(across(.cols = cols, ~ is.na(.x)) %>% all())
情况2:实际需求是保留「指定列中任意一列存在NA」的行
如果你的真实需求是保留那些在cols指定列里至少有一列是NA的行,需要将逻辑改为「任意满足」,可以用两种写法:
- 用
any配合across:
data %>% filter(across(.cols = cols, ~ is.na(.x)) %>% any())
- 用dplyr内置的
if_any(dplyr 1.0.0及以上版本支持),写法更简洁:
data %>% filter(if_any(.cols = cols, ~ is.na(.x)))
将上述代码用于示例数据,会返回day列为NA的6行数据,符合反向筛选的预期。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

