如何按多重依赖条件对R语言DataFrame进行分组过滤?
按Group分组筛选特定行的实现方案
输入数据
dput(infile) structure(list(Group = c("A", "A", "A", "A", "B", "B", "C", "C", "C", "C", "C", "C", "C", "D", "D", "D", "D"), Match_ID = c("Id224", "", "", "", "", "", "Id456", "", "Id111", "", "", "", "", "", "Id908", "", ""), Gene = c("Gene1", "Gene2", "Gene3", "Gene4", "Gene5", "Gene6", "Gene7", "Gene8", "Gene9", "Gene10", "Gene11", "Gene12", "Gene13", "Gene14", "Gene15", "Gene16", "Gene17"), TID = c(692L, 12589L, 966702L, 158L, 222985L, 225187L, 112L, 2256L, 658792L, 368800L, 22915L, 692L, 12589L, 966702L, 158L, 2256L, 658792L), Species = c("Species A", "", "", "", "", "", "", "", "Species B", "", "", "", "", "", "Species K", "", "")), class = "data.frame", row.names = c(NA, -17L))
筛选需求
- 按
Group列分组,检查Match_ID列是否存在非空值:- 若存在非空
Match_ID,筛选出**Match_ID非空且Species非空**的行,若有多行则保留第一行 - 若不存在任何非空
Match_ID,保留该组的第一行
- 若存在非空
尝试过的代码(存在局限)
outfile <- working %>% group_by(Group) %>% filter(row_number() == 1)
该代码仅能保留每组第一行,无法处理组内存在有效匹配行但不在第一行的情况,也无法筛选符合Match_ID和Species双非空的行。
解决方案代码
利用tidyverse的分组、标记、筛选逻辑实现需求:
library(tidyverse) # 核心处理逻辑 outfile <- infile %>% group_by(Group) %>% mutate( # 标记单行是否满足Match_ID非空且Species非空的条件 valid_row = nchar(Match_ID) > 0 & nchar(Species) > 0, # 标记组内是否存在至少一个有效行 has_valid = any(valid_row) ) %>% filter( # 按规则筛选:有有效行则取第一个有效行,无则取组内第一行 if (has_valid) valid_row else row_number() == 1 ) %>% # 移除临时辅助列 select(-valid_row, -has_valid) %>% ungroup() # 输出结果 dput(outfile)
结果验证
运行上述代码后,输出结果与预期完全一致:
structure(list(Group = c("A", "B", "C", "D"), Match_ID = c("Id224", "", "Id111", "Id908"), Gene = c("Gene1", "Gene5", "Gene9", "Gene15" ), TID = c(692L, 222985L, 658792L, 158L), Species = c("Species A", "", "Species B", "Species K")), class = "data.frame", row.names = c(NA, -4L))
内容的提问来源于stack exchange,提问作者aminards
相关产品推荐
相关产品推荐

