通过递归添加连接元素来查找组

时间:2018-05-13 18:05:51

标签: r recursion group-by

考虑我有一个5 x n矩阵,其中列代表n个不同的对象。现在,对于每个对象,我最多可以与其他对象建立5个连接。矩阵中的条目显示我有一个链接的对象。现在我想在这些对象之间找到组。应将组定义为直接或间接相互链接的所有对象。因此,对于对象“1”,我有一个与对象“2”的链接,对于对象2的链接到对象“3”和“4”,对象“3”和“4”没有进一步的链接,对象“1”,“ 2“,”3“和”4“构建一个组。

最后我想要一个向量,长度与指示对象属于哪个组的对象数相同。

所以当我在上面的例子中添加对象“5”和“6”时,它们彼此链接,而不是1,2,3,4,我会得到一个矢量,如:groups = c(1,1 ,1,1,2,2)

考虑我有一个非常大的矩阵,我想找到一种如何最有效地找到这些组的方法。

我使用dput()

添加了一个示例矩阵
Data<-structure(c(NA, NA, "2", NA, NA, NA, NA, NA, NA, NA, NA, NA, 
"4", NA, NA, NA, NA, "5", "7", NA, NA, NA, "8", "9", "7", NA, 
NA, "8", "9", "7", NA, NA, "9", NA, NA, NA, NA, NA, NA, "9", 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "13", NA, "12", 
NA, NA, NA, NA, NA, NA, NA, "15", "16", NA, NA, NA, "17", NA, 
"15", NA, NA, NA, "18", "16", NA, NA, "18", NA, NA, NA, NA, "19", 
NA, NA, NA, NA, NA, NA, NA, NA, NA, "20", NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, "24", NA, "23", NA, NA, NA, 
"25", NA, NA, NA, NA, "26", NA, NA, NA, "27", NA, NA, NA, NA, 
NA, "29", "27", NA, NA, "29", NA, NA, NA, NA, "31", "32", NA, 
NA, NA, NA, NA, NA, NA, NA, "33", "34", "31", NA, NA, "34", "36", 
"32", NA, NA, "36", "37", NA, NA, NA, "38", "39", "34", NA, NA, 
"39", "40", "36", NA, NA, "39", "40", "36", NA, NA, "40", NA, 
"37", NA, NA, NA, NA, NA, NA, NA, NA, NA, "39", NA, NA, NA, NA, 
"40", NA, NA, NA, NA, NA, NA, NA, NA, "42", NA, NA, NA, NA, NA, 
NA, NA, NA, NA, "45", NA, NA, NA, NA, "45", NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, "48", NA, NA, NA, NA, "49", NA, 
NA, NA, NA, "52", NA, NA, NA, NA, "53", "54", NA, NA, NA, "56", 
NA, "52", NA, NA, NA, NA, NA, NA, NA, NA, NA, "54", NA, NA, NA, 
NA, "55", NA, NA, NA, NA, "56", NA, NA, NA, NA, NA, NA, NA, "59", 
NA, "58", NA, NA, NA, "61", NA, NA, NA, "63", NA, NA, NA, NA, 
"63", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, "74", "71", NA, NA, "74", NA, "72", NA, NA, NA, 
NA, NA, NA, NA, "76", NA, NA, NA, NA, "77", NA, NA, NA, NA, "77", 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "87", NA, 
"83", NA, NA, "87", NA, "83", NA, NA, NA, NA, "85", NA, NA, NA, 
NA, "85", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "89", 
NA, NA, NA, NA, "89", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, "95", NA, "92", NA, NA, NA, NA, "93", NA, NA, 
NA, NA, NA, NA, NA, NA, NA, "95", NA, NA, NA, NA, NA, NA, NA, 
"97", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), .Dim = c(5L, 
98L), .Dimnames = list(NULL, c("1", "2", "3", "4", "5", "6", 
"7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", 
"18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", 
"29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", 
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", 
"51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", 
"62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", 
"73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", 
"84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", 
"95", "96", "97", "98")))

非常欢迎任何帮助! 非常感谢。

1 个答案:

答案 0 :(得分:1)

如果您将对象视为图形中的节点,将连接视为图形的边缘,那么您要求的是图形的连接组件。包igraph包含许多用于处理图形的工具,包括查找其连接的组件。因此,一种方法是将您的Data矩阵转换为图表的边缘列表,制作图表并查找组件。我发现你的Data矩阵的格式有点尴尬,所以转换到边缘列表只是蛮力,不是很优雅。在转换之后,其余的很容易。

## Convert your matrix to an edgelist
EL = matrix(data=NA, nrow=0, ncol=2)
for(i in 1:ncol(Data)) {
    for(j in 1:5) {
        if(!is.na(Data[j,i])) { EL = rbind(EL, c(i,as.numeric(Data[j,i]))) }
    }
}

让我们看一下目前在边缘列表中的内容。

head(EL, 10)
      [,1] [,2]
 [1,]    1    2
 [2,]    3    4
 [3,]    4    5
 [4,]    4    7
 [5,]    5    8
 [6,]    5    9
 [7,]    5    7
 [8,]    6    8
 [9,]    6    9
[10,]    6    7

如果您与矩阵进行比较,您可以看到它如何捕获相同的信息。它表示对象1连接到对象2.对象3连接到对象4.等。

让我们把它变成图表。

library(igraph)
G = graph_from_edgelist(EL, directed=FALSE)
plot(G, vertex.size=10, margin=-0.2)

Graph

现在,您想要的组只是连接的组件。 igraph中有一个功能。它返回的信息不仅仅是组,因此我只选择组部分。

components(G)$membership
 [1]  1  1  2  2  2  2  2  2  2  3  4  4  4  4  4  4  4  4  4  4  5  6  6  6  6
[26]  6  6  7  6  7  7  7  7  7  7  7  7  7  7  7  8  8  9  9  9 10 11 11 11 11
[51] 11 11 11 11 11 11 12 12 12 12 12 13 12 14 15 16 17 18 19 20 20 20 21 20 20
[76] 21 20 22 23 24 25 25 25 25 25 26 25 25 25 27 28 28 28 28 28 29 29

你可以看到对象(节点)1&amp;对象3,4,5,6,7,8和9在第2组中。对象10没有连接到其他任何东西,所以它本身就是一个组 - 第3组。