R语言:如何移除dataframe中gs_name列匹配多子串的行?
问题描述
我有一个名为all.gene.sets的数据框,其中gs_name列的字符串可能匹配redundant.gs向量中的任意子串。我需要移除所有存在此类匹配的行,但当前代码仅能移除匹配第一个子串的行,无法处理后续子串。
当前代码:
redundant.gs <- c("ANDERSON_BLOOD_CN54GP140_ADJUVANTED", "BUCASAS_PBMC_FLUARIX_FLUVIRIN") gene.sets <- all.gene.sets[!(all.gene.sets$gs_name %like% redundant.gs),]
测试数据:
all.gene.sets <- tibble::tribble( ~gs_cat, ~gs_subcat, ~gs_name, "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_DN", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_DN", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_DN", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_DN", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_DN", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_UP", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_UP", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_UP", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_UP", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_UP", "C7", "VAX", "ANDERSON_BLOOD_CN54GP140_ADJUVANTED_WITH_GLA_AF_AGE_18_45YO_1DY_UP", "C7", "VAX", "BUCASAS_PBMC_FLUARIX_FLUVIRIN_CAUCASIAN_MALE_AGE_18_40YO_HIGH_RESPONDERS_1DY_3DY_POSITIVE_PREDICTIVE_OF_TITER", "C7", "VAX", "BUCASAS_PBMC_FLUARIX_FLUVIRIN_CAUCASIAN_MALE_AGE_18_40YO_HIGH_RESPONDERS_1DY_3DY_POSITIVE_PREDICTIVE_OF_TITER", "C7", "VAX", "BUCASAS_PBMC_FLUARIX_FLUVIRIN_CAUCASIAN_MALE_AGE_18_40YO_HIGH_RESPONDERS_1DY_3DY_POSITIVE_PREDICTIVE_OF_TITER", "C7", "VAX", "BUCASAS_PBMC_FLUARIX_FLUVIRIN_CAUCASIAN_MALE_AGE_18_40YO_HIGH_RESPONDERS_1DY_3DY_POSITIVE_PREDICTIVE_OF_TITER", "C7", "VAX", "BUCASAS_PBMC_FLUARIX_FLUVIRIN_CAUCASIAN_MALE_AGE_18_40YO_HIGH_RESPONDERS_1DY_3DY_POSITIVE_PREDICTIVE_OF_TITER", "C7", "IMMUNESIGDB", "GSE21063_3H_VS_16H_ANTI_IGM_STIM_NFATC1_KOBCELL_DN", "C7", "IMMUNESIGDB", "GSE21063_3H_VS_16H_ANTI_IGM_STIM_NFATC1_KOBCELL_DN", "C7", "IMMUNESIGDB", "GSE21063_3H_VS_16H_ANTI_IGM_STIM_NFATC1_KOBCELL_DN", "C7", "IMMUNESIGDB", "GSE21063_3H_VS_16H_ANTI_IGM_STIM_NFATC1_KOBCELL_DN", "C7", "IMMUNESIGDB", "GSE21063_3H_VS_16H_ANTI_IGM_STIM_NFATC1_KOBCELL_DN", )
解决方案
原来的%like%操作符(常见于data.table或dplyr包)当右侧传入向量时,只会匹配第一个元素,因此无法处理多个子串。可以通过以下几种方法解决:
方法1:基础R + 正则表达式合并模式
将redundant.gs中的子串用|连接成一个正则表达式模式,再用grepl检测匹配:
redundant.pattern <- paste(redundant.gs, collapse = "|") gene.sets <- all.gene.sets[!grepl(redundant.pattern, all.gene.sets$gs_name), ]
方法2:dplyr + stringr 管道风格
如果你习惯用dplyr的管道语法,可以结合str_detect和filter实现:
library(dplyr) library(stringr) gene.sets <- all.gene.sets %>% filter(!str_detect(gs_name, paste(redundant.gs, collapse = "|")))
方法3:data.table 多模式处理
如果使用data.table,可直接传入合并后的正则表达式,或用sapply结合any()检测每个子串:
library(data.table) setDT(all.gene.sets) # 方式A:合并正则表达式 gene.sets <- all.gene.sets[!gs_name %like% paste(redundant.gs, collapse = "|")] # 方式B:逐行检测所有子串 gene.sets <- all.gene.sets[!sapply(gs_name, function(x) any(x %like% redundant.gs))]
以上方法都会移除gs_name列包含redundant.gs中任意子串的行,最终保留5行IMMUNESIGDB相关数据。
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

