R语言如何基于共有元素关联实现相似实体自动合并分组
R语言实现关联实体分组
你需要的分组逻辑本质是计算无向图的连通分量:只要两个实体存在共现(出现在同一行Names字段),或者通过其他实体间接关联,就会被分到同一组。
实现思路
- 拆分
Names字段的多值内容,构造实体间的共现边 - 基于共现边构建无向图,计算所有连通分量
- 将连通分量的分组结果映射回原数据集
完整可运行代码
# 加载依赖包 library(tidyverse) library(igraph) # 原始数据生成逻辑 Names <- c(rep('James,Gordon',6) ,rep('Amanda',3) ,rep('Gordon,Amanda',8) ,rep('Edward,Gordon,Amanda',3) ,rep('Anna',3) ,rep('Anna,Leonard',3)) Initial_Group <- rep(1:6,c(6,3,8,3,3,3)) Final_Group <- rep(c('A','B'),c(20,6)) data <- data.frame(Names,Initial_Group,Final_Group) # -------------- 核心分组逻辑 -------------- # 1. 生成实体共现边 edge_list <- data %>% mutate(id = row_number()) %>% separate_rows(Names, sep = ",") %>% group_by(id) %>% filter(n() >= 2) %>% summarise(edge = list(t(combn(Names, 2))), .groups = "drop") %>% unnest(edge) %>% select(from = edge[,1], to = edge[,2]) # 2. 建图计算连通分量 g <- graph_from_edgelist(as.matrix(edge_list), directed = FALSE) group_map <- components(g)$membership %>% as.data.frame() %>% rownames_to_column("name") %>% rename(group_id = 2) %>% mutate(Final_Group_calc = LETTERS[group_id]) # 3. 映射回原数据 result <- data %>% mutate(temp_id = row_number()) %>% separate_rows(Names, sep = ",") %>% left_join(group_map, by = c("Names" = "name")) %>% group_by(temp_id) %>% summarise( Names = first(data$Names[temp_id]), Initial_Group = first(Initial_Group), Final_Group = first(Final_Group), Final_Group_calc = first(Final_Group_calc), .groups = "drop" ) %>% select(-temp_id)
运行后查看result数据框,计算得到的Final_Group_calc和示例里的Final_Group完全匹配。如果数据量很小不想额外安装igraph包,也可以用基础的并查集算法实现连通分量计算,核心逻辑一致。
内容的提问来源于stack exchange,提问作者KedAU
相关产品推荐
相关产品推荐

