如何基于两个分组变量的共享值生成唯一无重复配对?
基于双分组变量生成唯一配对的实现方案
我已经实现了单分组变量下获取对象唯一配对的功能,现在需要扩展到双分组变量的场景:只要两个对象共享任意一个分组变量的值,就需要生成配对,但必须保证配对完全唯一——既不能出现B-C和C-B这类镜像重复,也不能因为同一对对象匹配多个分组变量而重复生成。
示例输入数据(基因场景)
df = data.frame(scaffold = c("A", "A", "B", "B", "B", "C", "C", "D","A"), geneID = c("162", "276", "64", "276", "281", "64", "162", "162","64"), Grouping2 = c("x1", "x2", "x3", "x1", "x2", "x3", "x1", "x2", "x3"), stringsAsFactors = F)
要求:以geneID和Grouping2为分组变量,生成scaffold的所有唯一配对。例如A和B同时匹配geneID=276和Grouping2=x1,但仅需保留一个A-B配对。
真实场景示例(人员关联场景)
数据集包含25530个个体,每行对应一个个体,包含Household(家庭)和Work(工作单位)两个分组变量。需要找出所有唯一个体配对:只要两个个体属于同一家庭或同一工作单位,就生成配对,同时避免任何重复。
示例数据:
temp <- data.frame(Person = c("A", "B", "C", "D", "E", "F"), Household = c("123 Any Street", "123 Any Street", "123 Any Street", "4 Second Street", "5 Third Street", "6 Last Street"), Work = c("One Company", "XYZ Tailoring", "XYZ Tailoring", "XYZ Tailoring", "XYZ Tailoring", "XYZ Tailoring"))
期望输出:包含from和to列的数据框,共12个唯一配对,镜像对(如B-C与C-B)视为重复,仅保留一个。
解决方案代码(R语言)
我们可以通过分别生成两个分组变量的配对→合并去重→过滤镜像对的步骤实现需求,这里使用dplyr和tidyr包处理:
library(dplyr) library(tidyr) # 定义生成单个分组变量配对的函数 generate_pairs <- function(data, group_col, target_col) { data %>% group_by({{group_col}}) %>% filter(n_distinct({{target_col}}) >= 2) %>% mutate(temp = list({{target_col}})) %>% unnest(temp) %>% filter({{target_col}} < temp) %>% select(from = {{target_col}}, to = temp) %>% distinct() } # 针对基因场景示例生成配对 gene_pairs <- generate_pairs(df, geneID, scaffold) group2_pairs <- generate_pairs(df, Grouping2, scaffold) final_scaffold_pairs <- bind_rows(gene_pairs, group2_pairs) %>% distinct() # 针对人员场景示例生成配对 household_pairs <- generate_pairs(temp, Household, Person) work_pairs <- generate_pairs(temp, Work, Person) final_person_pairs <- bind_rows(household_pairs, work_pairs) %>% distinct() # 查看人员场景的配对数量(应为12) nrow(final_person_pairs)
代码说明
generate_pairs函数:针对单个分组变量,生成目标列的唯一配对,同时直接过滤掉镜像对(通过{{target_col}} < temp确保from始终小于to)。- 分别对两个分组变量调用函数生成配对,再用
bind_rows合并。 - 最后用
distinct()去重,解决同一对对象因多个分组变量匹配导致的重复问题。
内容的提问来源于stack exchange,提问作者Michelle
相关产品推荐
相关产品推荐

