以这个链接ID的简单数据框架为例:
test <- data.frame(id1=c(10,10,1,1,24,8),id2=c(1,36,24,45,300,11))
> test
id1 id2
1 10 1
2 10 36
3 1 24
4 1 45
5 24 300
6 8 11
现在我想把所有链接的id组合在一起。"链接“指的是沿着链接链走下去,这样一个组中的所有id都被标记在一起。这是一种分支结构,即:
Group 1
10 --> 1, 1 --> (24,45)
24 --> 300
300 --> NULL
45 --> NULL
10 --> 36, 36 --> NULL,
Final group members: 10,1,24,36,45,300
Group 2
8 --> 11
11 --> NULL
Final group members: 8,11
现在我大概知道了我想要的逻辑,但不知道如何优雅地实现它,我正在考虑递归使用match
或%in%
来遍历每个分支,但这次我真的被难住了。
我追求的最终结果是:
result <- data.frame(group=c(1,1,1,1,1,1,2,2),id=c(10,1,24,36,45,300,8,11))
> result
group id
1 1 10
2 1 1
3 1 24
4 1 36
5 1 45
6 1 300
7 2 8
8 2 11
4条答案
按热度按时间l3zydbqr1#
Bioconductor包RBGL(BOOST图形库的R接口)包含一个函数
connectedComp()
,它标识图形中的连接组件--这正是您想要的。(To使用该函数,您首先需要安装graph和RBGL包,可用的有here和here。)
sr4lhrrt2#
在Josh的指点下,我找到了另一个答案,这个答案使用了
igraph
包,对于那些正在搜索并找到这个答案的人来说,我的test
数据集在图论中被称为“边列表”或“邻接列表”(http://en.wikipedia.org/wiki/Graph_theory)7uhlpewt3#
不使用软件包:
nue99wik4#
你说递归...我想我会超级简洁,而我在它。
试验数据
用于获取分组的递归函数
准备数据并在
取得成果
aveminrec()可能和你想的一样,但是我打赌有一种方法可以更直接地沿着每个分支向下,而不是重复ave(),ave()本质上是split()和lapply()。也许递归地split和lapply?实际上,它就像重复的部分分支,或者交替地稍微简化2个向量,而不会丢失组信息。
也许这其中的一部分可以用在真实的问题上,但是groupvalues()太密集了,至少在没有注解的情况下无法读取。我也没有检查过与使用ave并以这种方式翻转组的for循环相比的性能。