使用R dplyr删除多列均匹配指定正则表达式的行
解决方案
报错原因
你之前的代码报错是因为across里的表达式~ "^Het|^Hom"返回的是字符串,而filter()需要的是逻辑向量(TRUE/FALSE)来判断行是否保留。必须用grepl()对每个元素做正则匹配,生成逻辑值才能满足要求。
正确实现方式
你的需求是:保留至少有一列样本列以Het或Hom开头的行,等价于删除所有样本列都匹配^r|^n|^N|^Ref|^No_GT的行。以下是两种简洁的实现方式:
方式1:使用if_any(dplyr 1.0.0及以上版本推荐)
if_any可以直接判断指定列中是否至少有一个满足条件,语法更直观:
# 先获取样本列名(简化原代码) samples <- my_file %>% select(info:gene) %>% colnames() %>% setdiff(c("info", "gene")) # 过滤数据 trimmed <- my_file_sorted %>% filter(if_any(all_of(samples), ~ grepl("^Het|^Hom", .x)))
方式2:兼容旧版dplyr(用rowSums)
如果你的dplyr版本较低,没有if_any,可以通过统计每行满足条件的列数来判断:
trimmed <- my_file_sorted %>% filter(rowSums(across(all_of(samples), ~ grepl("^Het|^Hom", .x))) > 0)
反向逻辑实现(删除全匹配排除规则的行)
也可以直接反向判断:删除所有样本列都匹配^r|^n|^N|^Ref|^No_GT的行,效果完全一致:
trimmed <- my_file_sorted %>% filter(!if_all(all_of(samples), ~ grepl("^r|^n|^N|^Ref|^No_GT", .x)))
关键说明
all_of(samples):因为samples是字符向量存储的列名,用all_of()可以让dplyr正确识别这些列,避免把它当成变量名处理。grepl(pattern, .x):对列中每个元素执行正则匹配,返回TRUE/FALSE的逻辑向量,这是filter()能识别的输入格式。
内容的提问来源于stack exchange,提问作者Karthik Nair
相关产品推荐
相关产品推荐

