在igraph中将边缘属性添加到平行边缘

时间:2018-05-24 15:10:30

标签: r matrix igraph

我有一个带有一些平行边的图,如下面的邻接矩阵所示:

> as_adjacency_matrix(g)
45 x 45 sparse Matrix of class "dgCMatrix"
   [[ suppressing 45 column names ‘1’, ‘2’, ‘3’ ... ]]
   [[ suppressing 45 column names ‘1’, ‘2’, ‘3’ ... ]]

1  . . . 1 . . . . . . . . . . . . . . 1 1 2 1 2 1 1 . . . . . . . . . . . . . . . . . . . .
2  . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 2 . . . . . . . . . . . . . . . . .
3  . . . 1 . . . . . . . . . . . . . . . . . . 1 . 1 . 2 . . . . . . . . . . . . . . . . . .
4  1 . 1 . . . . . . . . . . . 2 . . . . . . . . . . . . . 1 1 . . . . . . . . . . . . . . .
5  . . . . . . . . . . . . . . 2 . . . . . . . 1 . . . . . . 1 . . . . . . . . . . . . . . .
6  . . . . . . . . . . . . . . . . . . . . . 1 . . . . . . . . 1 . . . . . . . . . . . . . .
7  . . . . . . . . . . . . . . . . . . . . . . . . . 1 . . . . . 1 1 . 1 1 . . . . . . . . .
8  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 . 1 . . . . . . . . .
9  . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 . . 1 . . . . . 1 1 . . . . . . .
10 . . . . . . . . . . . . . . . . . . . . . . . . . 2 . . . . . . . . . 2 . . . . . . . . .
11 . . . . . . . . . . . . . . . . . . . . . . 1 . . . . 1 . . . . . . . . . . . . . . . . .

我需要在边缘添加属性。幸运的是,节点之间的平行边缘将具有相同的属性。要添加的属性位于与邻接矩阵相同的矩阵中:

> edge_attr_mat
           1        2        3          4        5        6         7        8        9        10       11       12
1       0.00      0.0      0.0  68299.332      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
2       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
3       0.00      0.0      0.0 102016.916      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
4   68299.33      0.0 102016.9      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
5       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
6       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
7       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
8       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
9       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
10      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
11      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
12      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
13      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
14      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
15      0.00      0.0      0.0 380794.817 154931.3     0.00     0.000    0.000     0.00     0.000     0.00     0.00
16      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
17      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
18      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
....

我尝试使用此矩阵作为加权邻接矩阵来重新创建网络,以便现在存在边缘属性:

g<-graph_from_adjacency_matrix(edge_attr_mat, mode=c("undirected"), diag = F, weighted = T)

然而,我正在丢失平行边缘,因为它们被折叠到节点之间的单个边缘。

有没有办法使用基于函数或矩阵的运算将属性添加到边(和平行边)而不循环遍历每个条目?

更新

帮助回答的小型代表性数据集:

g <- make_empty_graph(n = 4) %>%
+     add_edges(c(1,2, 2,4, 3,4, 1,3, 1,4)) %>%
+     set_edge_attr("type", value = "friend") %>%
+     add_edges(c(1,3, 2,4), type = "col")
g <- as.undirected(g, mode = "each")
V(g)$name <-c ("A", "B", "C", "D")
edge_attr_mat<-matrix(data=c(0,1.1,2.12,1.2,1.1,0,0,2.3,2.12,0,0,1.6,1.2,2.3,1.6,0), nrow = 4) #This is the new edge attribute to be added

在上面的示例中,type边缘属性区分了2个平行边。新的边缘属性是两个节点之间相似性的度量,因此对于两个节点之间的所有并行边缘应该是相同的。

1 个答案:

答案 0 :(得分:1)

所以%u%似乎不起作用,因为它只组合了第一个匹配的边缘,并且不会更改第二个匹配边缘的任何属性。我认为最简单的方法是将图形转换为数据框并将它们合并在一起:

g2 <- graph_from_adjacency_matrix(edge_attr_mat, 'undirected', weighted = T)
V(g2)$name <-c ("A", "B", "C", "D")

gdf <- as_data_frame(g)
g2df <- as_data_frame(g2)

#dplyr also has function as_data_frame
gdf %>%
  dplyr::left_join(g2df) %>%
  graph_from_data_frame(F)