You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R中使用递归函数构建ID与主键的网络/连通关联分组

问题分析

这个需求本质是求二部图的连通分量:ID和Key是两类节点,ID与它关联的Key之间存在边,所有连通的节点属于同一组,最终提取每个组中的所有Key即可。
你编写的递归函数主要存在两个逻辑漏洞:

  • 循环中只要遇到第一个和最后一个元素无交集的ID组就直接return,没有遍历完所有可合并的ID组,漏了大量合并场景
  • 合并后没有对Key去重,也没有处理合并后和其他ID组新增的交集情况
实现方案

方案1:使用igraph包(最简洁稳定)

直接通过图连通分量计算,代码量少且不易出错:

library(igraph)
# 避免因子类型干扰,先转字符
dt$ID <- as.character(dt$ID)
dt$Key <- as.character(dt$Key)
# 构建无向二部图
g <- graph_from_data_frame(dt, directed = FALSE)
# 计算连通分量
clu <- components(g)
# 提取所有Key对应的分组,过滤掉ID节点
key_nodes <- unique(dt$Key)
key_groups <- split(key_nodes, clu$membership[key_nodes])
# 可选:把Key转回数值类型
key_groups <- lapply(key_groups, as.numeric)

方案2:基础R迭代实现(无需第三方包)

纯基础R语法,通过迭代合并的方式完成分组:

# 第一步:每个ID对应的Key去重,存储为列表
id_key <- lapply(split(dt$Key, dt$ID), unique)
groups <- list()

while(length(id_key) > 0) {
  # 取第一个ID的Key作为初始分组
  current_group <- id_key[[1]]
  id_key <- id_key[-1]
  changed <- TRUE
  
  # 迭代合并所有和当前组有交集的ID对应的Key
  while(changed) {
    changed <- FALSE
    for(i in seq_along(id_key)) {
      if(length(intersect(current_group, id_key[[i]])) > 0) {
        current_group <- union(current_group, id_key[[i]])
        id_key <- id_key[-i]
        changed <- TRUE
        break
      }
    }
  }
  # 合并完成的组存入结果
  groups[[length(groups)+1]] <- sort(current_group)
}
示例数据运行结果

两种方案运行你提供的示例数据,最终得到2个分组:

  • 分组1:1,2,3,4,7,8,9,11,15,17,18
  • 分组2:5

内容的提问来源于stack exchange,提问作者Ahad Zaman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 17:27:01