R语言筛选数据框中至少含2个指定列表元素的Groups分组
R实现按分组筛选满足匹配数量要求的行
测试数据准备
先加载示例数据和匹配列表:
# 待匹配的名称列表 The_list <- c('SP1','SP2','SP3') # 示例数据框 df <- structure(list(Names = c("SP1", "SP2", "SP3", "SP1", "SP4", "SP5", "SP2", "SP3", "SP6", "SP2", "SP7"), Groups = c("G1", "G1", "G1", "G2", "G3", "G4", "G5", "G5", "G5", "G6", "G6")), class = "data.frame", row.names = c(NA, -11L))
需求逻辑:仅保留数据框中,Names列至少包含2个The_list内元素的Groups分组的全部行。
方法1:Base R 原生实现(无需安装第三方包)
实现思路:先按Groups分组统计每个组内匹配The_list的去重名称数量,筛选出符合数量要求的分组,再从原数据中提取对应分组的所有行。
# 统计每个分组下,出现在The_list中的去重Names个数 group_valid_count <- tapply( X = df$Names, INDEX = df$Groups, FUN = \(name_col) sum(unique(name_col) %in% The_list) ) # 提取匹配数≥2的分组名称 keep_groups <- names(group_valid_count[group_valid_count >= 2]) # 子集得到最终结果 result <- df[df$Groups %in% keep_groups, ]
运行后输出结果和预期完全一致:
Names Groups 1 SP1 G1 2 SP2 G1 3 SP3 G1 7 SP2 G5 8 SP3 G5 9 SP6 G5
方法2:dplyr 管道流实现(tidyverse生态常用写法)
如果习惯使用tidyverse系列的语法,代码可读性更强:
library(dplyr) result <- df %>% group_by(Groups) %>% # 组内统计匹配数量,保留满足阈值的所有行 filter(sum(unique(Names) %in% The_list) >= 2) %>% ungroup()
提示:代码中的
unique()是为了避免同一个Name在组内重复出现时被重复计数,如果你的业务场景需要把重复出现的同名条目多次计数,直接去掉unique()即可。
内容的提问来源于stack exchange,提问作者chippycentra
相关产品推荐
相关产品推荐

