0

请你帮助我好吗?

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

将这种数据输入到 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, number, sep = "")

matrix1 <- matrix(data = rbinom(100,size=1,prob=0.5), nrow = 10, ncol = 10,
                  dimnames = list(rowlabels, columnlabels))
matrix2 <- matrix(data = rbinom(100,size=1,prob=0.5), nrow = 10, ncol = 10,
                  dimnames = list(rowlabels, 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中制作多层图?

非常感谢你!

4

1 回答 1

2

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

set.seed(666)
number <- seq(1:10)
row <- "row"
rowlabels <- paste(row, number, sep = "")
column <- "col"
columnlabels <- paste(column, number, sep = "")
matrix1 <- matrix(data = rbinom(100,size=1,prob=0.5), nrow = 10, ncol = 10,
                  dimnames = list(rowlabels, columnlabels))
matrix2 <- matrix(data = rbinom(100,size=1,prob=0.5), nrow = 10, ncol = 10,
                  dimnames = list(rowlabels, 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
于 2020-10-23T09:31:40.527 回答