我有一个data.table,看起来像这样:
# Load packages
library(data.table)
# Set RNG seed
set.seed(-1)
# Create dummy data
dt <- data.table(foo = sample(letters[1:10], 6),
bar = sample(letters[1:10], 6))
dt
#> foo bar
#> 1: g a
#> 2: h j
#> 3: j e
#> 4: a i
#> 5: d g
#> 6: i c
我想将所有相关元素组合在一起。我的意思是,例如,a
和g
在第一行中在一起,因此它们一起属于一个组(a
,g
)。但是a
和i
一起位于第4行,因此i
也属于该组(a
,g
,i
)。另外,i
与第6行的c
关联,因此c
也属于组(a
,g
,i
,{ {1}})。在第5行,c
和d
在一起,因此g
也属于该组(d
,a
,g
,{{ 1}},i
)。
应用此逻辑可获得以下预期结果。
c
我有一些代码可以达到这个目的,但是将d
嵌套在# Desired result
# [[1]]
# [1] a c d g i
# [[2]]
# [1] e h j
循环中以及对数据结构的某些笨拙处理使我认为这远非最佳。
mapply
给,
while
根据需要。
有没有更优雅,更有效的方法来实现这一目标?
答案 0 :(得分:5)
您的数据可以看作是具有不同连通性组件的图形。要分析此类数据,您可以使用库igraph
:
只需从边缘数据框创建图形:
library(data.table)
library(igraph)
set.seed(-1)
foo = sample(letters[1:10], 6)
bar = sample(letters[1:10], 6)
edges <- data.table(foo, bar)
net <- igraph::graph_from_data_frame(d = edges, directed = F)
然后您可以找到该图的孤立成分:
components(net)
# $membership
# g h j a d i e c
# 1 2 2 1 1 1 2 1
#
# $csize
# [1] 5 3
#
# $no
# [1] 2
或者获得每个组件中包含的顶点的更好列表:
split(names(V(net)), components(net)$membership)
# $`1`
# [1] "g" "a" "d" "i" "c"
#
# $`2`
# [1] "h" "j" "e"