如何将R中的两个图形结合起来形成多层网络?

问题描述

能帮我吗?

我从事生态互动,其中一些被建模为多层网络(准确地说是多重网络)。

将此类数据输入R的程序包 igraph 的最佳方法是使用边缘和节点列表。不幸的是,我的合作者从来没有像这样组织数据,而是将其作为入射矩阵(双向网络)。

我总是要求他们至少将那些矩阵精确地组织为具有相同的尺寸以及行和列的标签的顺序,以便可以轻松地将它们组合在一起。

手握这些矩阵,然后根据以下步骤运行一个代码

  1. 将两个或多个入射矩阵读入R;

  2. 提取其边缘和顶点列表;

  3. 向每个边缘列表添加有关边缘类型的信息;

  4. 将有关顶点类的信息添加到每个顶点列表中;

  5. 分别合并这些边列表和顶点列表;

  6. 将这些合并的列表读取到igraph中以创建多层图。

我正在寻找一个更简单的解决方案。我尝试使用功能 union ,但是它合并了图形及其边缘,而没有保留有关边缘类型的信息。看看在此示例中使用随机矩阵会发生什么:

number <- seq(1:10)

row <- "row"
rowlabels <- paste(row,number,sep = "")
column <- "col"
columnlabels <- paste(column,sep = "")

matrix1 <- matrix(data = rbinom(100,size=1,prob=0.5),nrow = 10,ncol = 10,dimnames = list(rowlabels,columnlabels))
matrix2 <- matrix(data = rbinom(100,columnlabels))
      
graph1 <- graph_from_incidence_matrix(matrix1,directed = F)
graph2 <- graph_from_incidence_matrix(matrix2,directed = F)
       
E(graph1)$type = "layer1"
E(graph2)$type = "layer2"
    
graph_multi <- union(graph1,graph2)
graph_multi
E(graph_multi)$type

是否有更简单的方法来组合两个或多个入射矩阵以在 igraph 中制作多层图?

非常感谢您!

解决方法

我将数据转换为数据帧,合并为一个边列表,并在最后一步制作图形。类似于以下内容:

set.seed(666)
number <- seq(1:10)
row <- "row"
rowlabels <- paste(row,number,sep = "")
column <- "col"
columnlabels <- paste(column,sep = "")
matrix1 <- matrix(data = rbinom(100,size=1,prob=0.5),nrow = 10,ncol = 10,dimnames = list(rowlabels,columnlabels))
matrix2 <- matrix(data = rbinom(100,columnlabels))


library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter,lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect,setdiff,setequal,union
library(igraph)
#> 
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:dplyr':
#> 
#>     as_data_frame,groups,union
#> The following objects are masked from 'package:stats':
#> 
#>     decompose,spectrum
#> The following object is masked from 'package:base':
#> 
#>     union

edb <- bind_rows(
  as.data.frame(as.table(matrix1)),as.data.frame(as.table(matrix2)),.id = "layer"
) %>%
  filter(Freq != 0) %>%
  select(
    from = Var1,to = Var2,layer
  )

# from,to,layer
head(edb)
#>   from   to layer
#> 1 row1 col1     1
#> 2 row3 col1     1
#> 3 row6 col1     1
#> 4 row7 col1     1
#> 5 row1 col2     1
#> 6 row6 col2     1

multig <- graph_from_data_frame(edb,directed=FALSE)
multig
#> IGRAPH c377bd8 UN-- 20 110 -- 
#> + attr: name (v/c),layer (e/c)
#> + edges from c377bd8 (vertex names):
#>  [1] row1 --col1 row3 --col1 row6 --col1 row7 --col1 row1 --col2 row6 --col2
#>  [7] row8 --col2 row1 --col3 row2 --col3 row5 --col3 row8 --col3 row9 --col3
#> [13] row10--col3 row3 --col4 row4 --col4 row5 --col4 row8 --col4 row9 --col4
#> [19] row10--col4 row2 --col5 row4 --col5 row5 --col5 row6 --col5 row8 --col5
#> [25] row9 --col5 row10--col5 row4 --col6 row6 --col6 row8 --col6 row1 --col7
#> [31] row2 --col7 row4 --col7 row5 --col7 row8 --col7 row9 --col7 row10--col7
#> [37] row1 --col8 row3 --col8 row4 --col8 row6 --col8 row7 --col8 row9 --col8
#> [43] row10--col8 row1 --col9 row2 --col9 row4 --col9 row6 --col9 row7 --col9
#> + ... omitted several edges

table(E(multig)$layer)
#> 
#>  1  2 
#> 55 55