将边缘列表映射到邻接矩阵(并将它们相加)

时间:2018-11-15 12:34:36

标签: r igraph adjacency-matrix weighted-graph

我想使用R将许多(无向的)友谊网络(以边列表形式)映射到由所有可能的节点(即人)组成的邻接矩阵。首先,我构建一个较小的4人圈子x <- c(1, 2, 3, 4),该圈子由6个唯一的边(1-2、1-3、1-4、2-3、2-4、3-4)组成。然后,我将这6个独特的边集折叠到一个列表中,以便可以使用igraph应用程序将其转换为对称矩阵(见下文)。

x = c(1,2,3,4)
x_pairs = combn(x, 2)
List <- split(x_pairs, rep(1:ncol(x_pairs), each = nrow(x_pairs)))
library(purrr)
new_list <- purrr::flatten(List)
g <- make_graph(unlist(new_list), directed = F)
m <- as_adjacency_matrix(g, sparse = F)
m

     [,1] [,2] [,3] [,4]
[1,]    0    1    1    1
[2,]    1    0    1    1
[3,]    1    1    0    1
[4,]    1    1    1    0

我的数据集中有一个以上这样的较小的友谊圈子,其中不超过50个成员,这些圈子的成员可以重叠也可以不重叠。因此,我的问题是如何以两种不同的方式将一系列较小的矩阵值(如上面的m映射到50 x 50邻接矩阵:

(1),无需重复:例如,如果3和4在一个圆圈中是朋友,但它们也在另一个圆圈中链接,则3和4之间的边应保持1(但不等于2) (2)累积:如果多个圆圈中的关系表示更强的友谊,则将这些圆圈映射到加权邻接矩阵中可能会更有信息,该矩阵中的每个单元格代表不同圆圈中行和列id的友谊的累积计数。在3和4的情况下,其边缘值应为1 +1 = 2。

我已经检查了this和其他先前的主题,但是似乎无法弄清楚该怎么做,如果有人可以启发我,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

有多种方法可以实现它。与直接处理邻接矩阵相比,用igraph中的图形理论术语进行处理看起来有点乏味。让

circles <- list(1:3, 2:4) # Friendship circles with identities 1, ..., n
n <- max(unlist(circles)) # Total number of people
nM <- matrix(0, n, n) # n x n matrix of zeroes

然后

adjs <- lapply(circles, function(cr) {nM[cr, cr] <- 1; nM[cbind(cr, cr)] <- 0; nM})

是每个友谊圈子的n x n个邻接矩阵的列表(在每种情况下,大多数情况下为零)。

然后可以通过以下两种方式获得两种类型的聚合矩阵:

(adj1 <- Reduce(`+`, adjs))
#      [,1] [,2] [,3] [,4]
# [1,]    0    1    1    0
# [2,]    1    0    2    1
# [3,]    1    2    0    1
# [4,]    0    1    1    0
(adj2 <- 1 * (adj1 > 0))
#      [,1] [,2] [,3] [,4]
# [1,]    0    1    1    0
# [2,]    1    0    1    1
# [3,]    1    1    0    1
# [4,]    0    1    1    0