R语言dplyr::filter()使用负索引筛选数据失效问题
问题根因
你写的代码跑不通有两个直接原因:
- 拼写错误:筛选语句里的对象名写成了
daframe,和实际创建的dataframe不一致,会直接触发对象不存在的报错 - 逻辑不符合
filter()的入参规则:dataframe[,c(-1,-4,-5,-6)]=="pass"返回的是多列组成的逻辑矩阵,而filter()要求传入的判断条件对每一行返回单个逻辑值(决定该行保留/丢弃)。你需要的是「指定列中任意一列值为"pass"就保留该行」的行级判断,直接传入逻辑矩阵会触发列循环匹配,完全无法得到预期结果。另外你的负索引漏排除了第7列blah2,实际用的时候要注意列数统计准确。
可直接运行的方案
dplyr 1.0.0及以上版本可以直接用if_any()函数,完美适配「任意选中列满足条件即保留行」的需求,原生支持负索引选列,不需要逐个写列名:
library(dplyr) dataframe %>% filter(if_any(c(-1, -4, -5, -6, -7), ~ .x == "pass"))
运行结果和你手动写breakfast=="pass"|lunch=="pass"的预期输出完全一致:
id breakfast lunch dinner sweets blah1 blah2 1 1 pass fail fail fail 1 1 2 3 pass fail pass pass 3 3
如果你用的dplyr版本较低没有if_any(),可以用基础R的Reduce实现等价逻辑:
dataframe %>% filter(Reduce(`|`, lapply(.[, c(-1, -4, -5, -6, -7)], function(col) col == "pass")))
真实数据集使用时,只需要把c(-1, -4, -5, -6, -7)里的负索引改成你要排除的列位置即可,不需要枚举所有参与筛选的列名。
内容的提问来源于stack exchange,提问作者yoo
相关产品推荐
相关产品推荐

