在R的dplyr中按多条件筛选数据框:优先保留representative genome行
需求实现:筛选数据框的特定行
数据结构
用户给出的数据框定义如下:
dt<-data.frame(assembly_accession=c("id1","id2","id3","id3","id4","id5","id6","id7"), refseq_category=c("na","na","na","representative genome","na","na","na","na"), assembly_level=c("Contigs","Contigs","Complete Genome","Complete Genome","Contigs","Contigs","Contigs","Complete Genome"), link=c("ftp1","ftp2","ftp3","ftp4","ftp5","ftp6","ftp7","ftp8"))
需求说明
需要筛选出assembly_level列为"Complete Genome"的行,但对于同一assembly_accession的记录:
- 若存在
refseq_category为"representative genome"的行,仅保留该行 - 若不存在,则保留所有
assembly_level为"Complete Genome"的行(本案例中这类情况是id7)
用户尝试的代码(存在逻辑问题):
dt %>% filter(assembly_level=="Complete Genome") %>% if(refseq_category=="representative genome") filter(.) else
解决方案
可以用dplyr的分组过滤逻辑实现,核心思路是先筛选出符合assembly_level条件的行,再按assembly_accession分组,根据组内是否存在目标记录来过滤:
library(dplyr) dt_filtered <- dt %>% # 第一步:筛选assembly_level为Complete Genome的行 filter(assembly_level == "Complete Genome") %>% # 按assembly_accession分组 group_by(assembly_accession) %>% # 第二步:分组过滤 filter( if(any(refseq_category == "representative genome")) { refseq_category == "representative genome" } else { TRUE } ) %>% # 取消分组 ungroup()
结果验证
运行上述代码后,dt_filtered会包含两行:
id3对应的refseq_category为"representative genome"的行id7对应的行
完全符合需求。
内容的提问来源于stack exchange,提问作者AQ7
相关产品推荐
相关产品推荐

