R语言如何通过逻辑型DataFrame快速筛选主数据框目标行
R按同维度逻辑数据框筛选目标行
问题说明
现有两个维度完全一致的数据框,第一个为存储数值的主数据框,第二个为存储筛选标记的逻辑型数据框,构造代码与示例内容如下:
# 主数据框 df <- data.frame( x= c(1:10), y= c(11:20), z= c(21:30)) df # x y z #1 1 11 21 #2 2 12 22 #3 3 13 23 #4 4 14 24 #5 5 15 25 #6 6 16 26 #7 7 17 27 #8 8 18 28 #9 9 19 29 #10 10 20 30 # 逻辑筛选数据框 logic_df <- data.frame( x = c(rep(TRUE,2),rep(FALSE,8)), y = c(rep(TRUE,3),rep(FALSE,7)), z = c(rep(FALSE,9),rep(TRUE,1)) ) logic_df # x y z #1 TRUE TRUE FALSE #2 TRUE TRUE FALSE #3 FALSE TRUE FALSE #4 FALSE FALSE FALSE #5 FALSE FALSE FALSE #6 FALSE FALSE FALSE #7 FALSE FALSE FALSE #8 FALSE FALSE FALSE #9 FALSE FALSE FALSE #10 FALSE FALSE TRUE
需要实现的筛选规则:只要某一行在逻辑数据框的任意列对应位置为TRUE,就保留整行;所有位置全为FALSE的行删除,期望输出结果如下:
x y z 1 1 11 21 2 2 12 22 3 3 13 23 4 10 20 30
高效实现方案
基础R实现(无依赖,最优方案)
利用R中逻辑值运算的原生特性:TRUE参与数值运算时自动转为1,FALSE自动转为0,对逻辑数据框按行求和,行和大于0即代表该行存在至少一个TRUE,直接作为行索引即可,一行代码完成筛选:
res <- df[rowSums(logic_df) > 0, ]
运行后得到的res和期望结果完全一致,代码简洁且运行效率最高。
其他可选实现
如果日常使用tidyverse生态,也可以用dplyr写法实现:
library(dplyr) # 写法1:直接沿用行求和逻辑,性能和基础R接近 res <- df %>% filter(rowSums(logic_df) > 0) # 写法2:按列显式匹配判断,逻辑可读性更强 res <- df %>% filter(if_any(everything(), ~ logic_df[[cur_column()]]))
注意事项
- 上述方法默认两个数据框行数、列顺序完全匹配,如果列顺序不一致需要先对齐列,否则会出现筛选错位
- 如果需要筛选所有列对应位置全为TRUE的行,只需要把判断条件改为
rowSums(logic_df) == ncol(logic_df)即可 - 如果逻辑数据框存在NA值,可以补充
na.rm = TRUE参数避免结果出现NA:rowSums(logic_df, na.rm = TRUE) > 0
内容的提问来源于stack exchange,提问作者Ammar Gamal
相关产品推荐
相关产品推荐

