dplyr中如何仅使用filter函数过滤NA值数量大于1的行?
dplyr中仅用filter筛选NA数量大于1的行的实现方案
原代码失效的核心原因
你最初尝试的写法无法得到正确结果,本质是across在默认的列向量化计算上下文里,会把每一列作为独立输入计算整列的NA总数,最终返回的是和列数等长的判断向量,完全不符合filter需要的逐行逻辑判断要求。
极简实现方案
完全不需要借助mutate生成中间列,也不需要额外加rowwise逐行遍历,直接把逐行NA统计的逻辑嵌入filter的判断条件即可:
airquality %>% filter(rowSums(is.na(across(everything()))) > 1)
方案特点
- 全程仅使用filter完成筛选操作,无多余中间计算步骤,完全符合你对代码简洁性的要求
- 计算逻辑为纯向量化实现,相比你之前用
rowwise() + mutate的写法,在大尺寸数据集上执行速度会有数倍提升 - 计算链路清晰:
is.na(across(everything()))会生成和原数据维度完全一致的逻辑矩阵,矩阵中每个元素代表对应位置是否为缺失值;rowSums()直接逐行统计逻辑矩阵里的TRUE(即缺失值)总数,和阈值1做比较后返回行级筛选逻辑。
等价的across语法写法
如果你更习惯用across的语法组织判断逻辑,也可以写成下面的等价形式,筛选效果和上面的代码完全一致:
airquality %>% filter(across(everything(), is.na) %>% rowSums() > 1)
注意:以上写法都不需要额外添加
rowwise()分组,因为rowSums本身就是逐行处理的向量化函数,添加rowwise反而会触发逐行遍历的低效率计算逻辑。
内容的提问来源于stack exchange,提问作者Laura
相关产品推荐
相关产品推荐

