如何用R筛选DataFrame中Val列以303或305开头的行?
问题:筛选DataFrame中Val列以"303"或"305"开头的行
原始DataFrame
df BEN_ID Val_1 Val_2 Val_3 Val_4 Val_5 AGE GENDER 1 ID1 vA303 . . . . 25 F 2 ID1 9351 A303 53019 49390 F5D12 52 F 3 ID2 541AZ 1120 462 4019 A36B0 58 M 4 ID2 30302 5939 2768 4019 2724 65 M 5 ID2 305A1 78652 9190 4019 33829 61 M 6 ID3 305A3 29590 5715 . . 53 M 7 ID3 Z57B9 35981 5849 570 4254 35 M 8 ID3 5693 78900 30590 30500 Z25H2 19 M 9 ID3 7AD59 7881 30301 78900 78791 57 M 10 ID4 7AD59 5780 53530 30390 3051 57 F
需求说明
需要筛选出Val_1至Val_5中任意一列的值以"303"或"305"开头的行,期望输出如下:
BEN_ID Val_1 Val_2 Val_3 Val_4 Val_5 AGE GENDER 4 ID2 30302 5939 2768 4019 2724 65 M 5 ID2 305A1 78652 9190 4019 33829 61 M 6 ID3 305A3 29590 5715 . . 53 M 8 ID3 5693 78900 30590 30500 Z25H2 19 M 9 ID3 7AD59 7881 30301 78900 78791 57 M 10 ID4 7AD59 5780 53530 30390 3051 57 F
尝试的代码及问题
使用以下dplyr代码时出现问题:
library(dplyr) diag_cols = names(df %>% select(starts_with("Val"))) dat_read = dat_read %>% mutate(across(matches("Val"),as.character)) values = "303|3050" subdf = df %>% filter(grepl(values,do.call(paste,c(df[,diag_cols],sep = ","))))
- 用
values = "303|3050"会误选第1行(因为Val_1的值vA303包含"303",但并非以"303"开头) - 改用
values = "^303|^305"后,由于拼接字符串的逻辑,^仅匹配整个拼接串的开头,无法正确判断每个Val列的开头,导致输出错误
解决方案
方法1:使用if_any(推荐,dplyr 1.0.0+支持)
直接对每个Val列单独检查,判断是否有任意一列满足开头匹配条件:
library(dplyr) # 先将所有Val列转为字符型(确保匹配逻辑正确) df <- df %>% mutate(across(starts_with("Val"), as.character)) # 筛选任意Val列以"303"或"305"开头的行 subdf <- df %>% filter(if_any(starts_with("Val"), ~ grepl("^303|^305", .x, ignore.case = FALSE)))
if_any(starts_with("Val"), ...):遍历所有以Val开头的列,检查每一行是否存在任意一列满足后续条件grepl("^303|^305", .x, ignore.case = FALSE):^限定匹配字符串开头,ignore.case=FALSE确保区分大小写,避免误判vA303这类非开头匹配的情况
方法2:使用rowwise + c_across
如果版本不支持if_any,可以用逐行处理的方式:
subdf <- df %>% mutate(across(starts_with("Val"), as.character)) %>% rowwise() %>% filter(any(grepl("^303|^305", c_across(starts_with("Val")), ignore.case = FALSE))) %>% ungroup()
rowwise():将数据框转为逐行处理模式c_across(starts_with("Val")):提取当前行的所有Val列值组成向量any(...):判断当前行是否有任意一个值满足匹配条件
运行上述代码后,即可得到符合期望的筛选结果。
内容的提问来源于stack exchange,提问作者Triparna Poddar
相关产品推荐
相关产品推荐

