合并tibble中值相交的行并移除已使用行的实现方法
合并tibble中存在交集的列表行
我手头有这么个tibble:
tibble(id = list(c(1, 3), c(2, 3), c(1, 3), c(1, 2), c(4, 5)))
想把里面值有交集的行合并到一块儿,同时删掉已经被合并的行,最终要得到这样的结果:
tibble(id = list(c(1, 2, 3), c(4, 5)))
解决方案
这个问题本质是找元素的连通组——只要两个列表共享某个元素,就属于同一组。用igraph包处理最方便,步骤如下:
- 把每个列表里的元素拆成两两配对的“边”(比如
c(1,3)就拆成1和3的连接) - 用这些边构建无向图,找出图里的连通分量
- 把每个连通分量里的元素合并去重,生成新的tibble
直接上代码:
library(tibble) library(igraph) # 原始数据 df <- tibble(id = list(c(1, 3), c(2, 3), c(1, 3), c(1, 2), c(4, 5))) # 生成所有元素配对的边 edges <- unlist(lapply(df$id, function(x) combn(x, 2, simplify = FALSE)), recursive = FALSE) edges <- do.call(rbind, edges) # 构建图并获取连通分量 g <- graph_from_edgelist(edges, directed = FALSE) component_members <- components(g)$membership # 按连通组分组合并元素,去重后排序 result <- tibble( id = lapply(unique(component_members), function(group) { sort(unique(names(component_members[component_members == group]))) |> as.numeric() }) ) print(result)
运行这段代码就能得到预期的结果。如果不想用第三方包,也可以写循环逐一检查合并,但数据量大的时候igraph的效率会高很多。
内容的提问来源于stack exchange,提问作者sparklink
相关产品推荐
相关产品推荐

