英文:
Adding vertices ('type') aurguments to list of igraph objects
问题
我有一个包含植物-传粉者相互作用的边缘列表的列表,用于多个双分图网络。我正在尝试使用 igraph
R包将这些列表转换为双分图关联矩阵以进行分析。
我在尝试将顶点(igraph::V
)添加到列表 graph_list
中的igraph对象时遇到了问题。请注意:我希望避免使用 for
循环解决方案,因为我的完整数据集是包含238个网络的列表,包含80,000多条边。
我提供一个可重现的数据示例:
network_list <- replicate(10, expr = {
data.frame(plant = paste('plnt', '_', sample(x = letters, size = 10, replace = T), sep = ""),
pollinator = paste('pollinator', '_', sample(x = letters, size = 10, replace = T), sep = ""))
}, simplify = F)
library(tidyverse)
library(dplyr)
library(igraph)
我尝试将顶点序列添加到列表中的每个图中。但以下代码不按我期望的方式工作:
graph_list <- lapply(network_list, graph_from_data_frame) #从边缘列表创建igraph对象的列表
list_mapping <- lapply(graph_list, bipartite.mapping) #将网络映射为双分图
list_type <- lapply(list_mapping, with, type) #提取每个网络的顶点列表
graph_list <- mapply(c, graph_list, list_type) #尝试将顶点添加到graph_list
incidence_list <- lapply(graph_list, get.incidence) #出错
get.incidence
期望带有 types
参数的双分图 graph
对象。
作为参考,我正在遵循适用于单个网络的代码,该代码有效:
example_network <- network_list[[1]] #选择一个示例网络
net_graph <- graph_from_data_frame(example_network) #将边缘列表转换为图
bipartite.mapping(net_graph) #创建双分图
输出:
$res
[1] TRUE
$type
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
V(net_graph)$type <- bipartite.mapping(net_graph)$type #计算顶点('type')并将其添加为图的向量
incidence_matrix <- get.incidence(net_graph) #生成关联矩阵
incidence_matrix[incidence_matrix > 1] <- 1 #强制0/1边,某些行在随机列表中重复出现导致值大于1
我的期望是列表中每个关联矩阵的格式如下:
poll_z poll_g poll_h poll_d poll_r poll_i poll_l poll_x
plnt_v 1 0 0 0 0 0 0 0
plnt_o 0 1 0 0 0 0 0 0
plnt_r 0 0 1 0 1 0 0 0
plnt_c 0 0 0 1 0 0 0 0
plnt_x 0 0 0 1 0 0 0 0
plnt_a 0 0 0 0 0 1 1 0
plnt_j 0 0 0 0 0 0 1 0
plnt_h 0 0 0 0 0 0 0 1
此外,强制将列表中的所有可能重复值(即值大于1的值)设置为1将非常有帮助。
英文:
I have a list of lists containing the edgelists of plant-pollinator interactions, for a number bipartite networks. Using the igraph
r-package I am attempting to convert these lists into bipartite incidence matrices for analysis.
I am having trouble adding vertices (igraph::V
) to the igraph objects in the list graph_list
. Note: I would prefer to avoid for
loop solutions as my complete dataset is a list of 238 networks comprising >80k edges.
Reproducable example of my data.
network_list <- replicate(10, expr = {data.frame(plant = paste('plnt', '_', sample(x = letters, size = 10, replace = T), sep = ""),pollinator = paste('pollinator', '_', sample(x = letters, size = 10, replace = T), sep = ""))}, simplify = F)
library(tidyverse)
library(dplyr)
library(igraph)
I am trying to add the vertex sequence to each graph in the list. But the following code is not working as I am expecting.
graph_list <- lapply(network_list, graph_from_data_frame) #creates list of igraph objects from list of edgelists
list_mapping <- lapply(graph_list, bipartite.mapping) #map networks as bipartit
list_type<- lapply(list_mapping, with, type) #extract list of vertices for each network
graph_list <- mapply(c, graph_list, list_type) #ATTEMPT to add vertices to graph_list
incidence_list <- lapply(graph_list, get.incidence) #breaks
`Error in FUN(X[[i]], ...) : Not a graph object
get.incidence
is expecting bipartite graph
objects with types argument supplied.
For reference, I am following code which works for a single network.
example_network <- network_list[[1]] #select one network for example
net_graph <- graph_from_data_frame(example_network) #take the edge list and make it into a graph
bipartite.mapping(net_graph) #make bipartite graph
OUTPUT:
$res
[1] TRUE
$type
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
V(net_graph)$type <- bipartite.mapping(net_graph)$type #compute vertices ('type') and add as vector to graph
incidence_matrix <- get.incidence(net_graph) #produce incidence matrix
incidence_matrix[incidence_matrix > 1] <- 1 #force 0/1 edge, some rows are duplicated in random list resulting in values >1
where my desired format of each incidence matrix in the list is:
<pre> poll_z poll_g poll_h poll_d poll_r poll_i poll_l poll_x
plnt_v 1 0 0 0 0 0 0 0
plnt_o 0 1 0 0 0 0 0 0
plnt_r 0 0 1 0 1 0 0 0
plnt_c 0 0 0 1 0 0 0 0
plnt_x 0 0 0 1 0 0 0 0
plnt_a 0 0 0 0 0 1 1 0
plnt_j 0 0 0 0 0 0 1 0
plnt_h 0 0 0 0 0 0 0 1</pre>
Also it would be a great help to have all possible duplicate values (i.e. values >1) in the list of matrices forced to equal 1.
答案1
得分: 2
你的 `mapply` 调用使用 `c` 是不正确的。你可以编写自己的小型 lambda 函数,例如 `function(g, type) { V(g)$type <- type; return(g) }` 直接放在 `mapply` 内部,虽然也有 igraph 函数 `vertex_attr<-` 可以直接实现相同的功能。
我倾向于使用 `Map` 而不是 `mapply`,因为它本质上是相同的函数,但它从不尝试像 `mapply` 那样“简化”输出,这可能导致意外的结果。(`Map(...)` 与 `mapply(..., SIMPLIFY = FALSE)` 完全相同,但键入更少)。
最后,要将矩阵的列表转换为 0 保持为 0,所有正数变为 1,我们可以使用 `lapply(incidence_list, sign)`。
所以你的整个代码可能是这样的:
``` r
library(tidyverse)
library(igraph)
graph_list <- lapply(network_list, graph_from_data_frame)
list_mapping <- lapply(graph_list, bipartite.mapping)
list_type <- lapply(list_mapping, with, type)
graph_list <- Map(`vertex_attr<-`, graph_list, "type", value = list_type)
incidence_list <- lapply(graph_list, get.incidence)
incidence_list <- lapply(incidence_list, sign)
而你的结果将会是:
incidence_list
#> [[1]]
#> pollinator_z pollinator_h pollinator_a pollinator_c pollinator_x
#> plnt_m 1 0 0 0 0
#> plnt_k 0 1 1 0 1
#> plnt_l 0 0 0 1 0
#> plnt_c 0 0 0 0 0
#> plnt_y 0 0 0 0 0
#> plnt_u 1 0 0 0 0
#> pollinator_b pollinator_n pollinator_l pollinator_i
#> plnt_m 0 0 1 1
#> plnt_k 0 0 0 0
#> plnt_l 0 0 0 0
#> plnt_c 1 0 0 0
#> plnt_y 0 1 0 0
#> plnt_u 0 0 0 0
#>
#> [[2]]
#> pollinator_j pollinator_t pollinator_o pollinator_s pollinator_l
#> plnt_e 1 0 0 0 0
#> plnt_t 0 1 0 0 0
#> plnt_j 0 0 1 0 0
#> plnt_v 0 0 0 1 0
#> plnt_o 0 0 1 0 1
#> plnt_p 0 0 0 0 0
#> plnt_b 0 0 0 0 0
#> plnt_u 0 0 0 0 0
#> pollinator_c pollinator_r pollinator_f
#> plnt_e 0 1 0
#> plnt_t 0 0 0
#> plnt_j 0 0 0
#> plnt_v 0 0 0
#> plnt_o 0 0 0
#> plnt_p 1 0 0
#> plnt_b 0 1 0
#> plnt_u 0 0 1
#>
#> [[3]]
#> pollinator_k pollinator_u pollinator_x pollinator_g pollinator_o
#> plnt_a 1 0 0 0 0
#> plnt_e 0 1 0 0 0
#> plnt_u 0 0 1 0 0
#> plnt_w 0 0 0 1 0
#> plnt_i 0 0 0 0 1
#> plnt_d 0 0 0 0 0
#> plnt_r 0 0 0 0 0
#> plnt_h 0 0 0 0 0
#> pollinator_s pollinator_e pollinator_h
#> plnt_a 0 0 1
#> plnt_e 0 0 0
#> plnt_u 0 0 0
#> plnt_w 0 0 0
#> plnt_i 0 0 0
#> plnt_d 1 0 0
#> plnt_r 0 1 0
#> plnt_h 1 0 0
#>
#> [[4]]
#> pollinator_r pollinator_i pollinator_l pollinator_m pollinator_z
#> plnt_n 1 0 0 0 0
#> plnt_d 0 1 0 0 0
#> plnt_g 0 0 1 0 0
#> plnt_v 0 0 0 1 0
#> plnt_y 0 0 0 0 1
#> plnt_l 0 0 0 0 0
#> plnt_r 0 0 0 0 0
#> plnt_j 0 0 0 0 0
#> pollinator_k pollinator_o pollinator_c pollinator_j pollinator_x
#> plnt_n 0 0 0 0 0
<details>
<summary>英文:</summary>
You `mapply` call using `c` isn't correct. You could write your own little lambda function such as `function(g, type) { V(g)$type <- type; return(g) }` directly inside `mapply`, though there is also the igraph function `vertex_attr<-` which can do the same thing directly.
I tend to use `Map` rather than `mapply`, because it is essentially the same function but never attempts to "simplify" the output the way `mapply` does, which can lead to unexpected results. (`Map(...)` is identical to `mapply(..., SIMPLIFY = FALSE)` but requires fewer keystrokes).
At the end, to convert the list of matrices such that 0s remain 0s and all positive numbers become 1, we can do `lapply(incidence_list, sign)`
So your whole code might be something like this:
``` r
library(tidyverse)
library(igraph)
graph_list <- lapply(network_list, graph_from_data_frame)
list_mapping <- lapply(graph_list, bipartite.mapping)
list_type <- lapply(list_mapping, with, type)
graph_list <- Map(`vertex_attr<-`, graph_list, "type", value = list_type)
incidence_list <- lapply(graph_list, get.incidence)
incidence_list <- lapply(incidence_list, sign)
And your result would be:
incidence_list
#> [[1]]
#> pollinator_z pollinator_h pollinator_a pollinator_c pollinator_x
#> plnt_m 1 0 0 0 0
#> plnt_k 0 1 1 0 1
#> plnt_l 0 0 0 1 0
#> plnt_c 0 0 0 0 0
#> plnt_y 0 0 0 0 0
#> plnt_u 1 0 0 0 0
#> pollinator_b pollinator_n pollinator_l pollinator_i
#> plnt_m 0 0 1 1
#> plnt_k 0 0 0 0
#> plnt_l 0 0 0 0
#> plnt_c 1 0 0 0
#> plnt_y 0 1 0 0
#> plnt_u 0 0 0 0
#>
#> [[2]]
#> pollinator_j pollinator_t pollinator_o pollinator_s pollinator_l
#> plnt_e 1 0 0 0 0
#> plnt_t 0 1 0 0 0
#> plnt_j 0 0 1 0 0
#> plnt_v 0 0 0 1 0
#> plnt_o 0 0 1 0 1
#> plnt_p 0 0 0 0 0
#> plnt_b 0 0 0 0 0
#> plnt_u 0 0 0 0 0
#> pollinator_c pollinator_r pollinator_f
#> plnt_e 0 1 0
#> plnt_t 0 0 0
#> plnt_j 0 0 0
#> plnt_v 0 0 0
#> plnt_o 0 0 0
#> plnt_p 1 0 0
#> plnt_b 0 1 0
#> plnt_u 0 0 1
#>
#> [[3]]
#> pollinator_k pollinator_u pollinator_x pollinator_g pollinator_o
#> plnt_a 1 0 0 0 0
#> plnt_e 0 1 0 0 0
#> plnt_u 0 0 1 0 0
#> plnt_w 0 0 0 1 0
#> plnt_i 0 0 0 0 1
#> plnt_d 0 0 0 0 0
#> plnt_r 0 0 0 0 0
#> plnt_h 0 0 0 0 0
#> pollinator_s pollinator_e pollinator_h
#> plnt_a 0 0 1
#> plnt_e 0 0 0
#> plnt_u 0 0 0
#> plnt_w 0 0 0
#> plnt_i 0 0 0
#> plnt_d 1 0 0
#> plnt_r 0 1 0
#> plnt_h 1 0 0
#>
#> [[4]]
#> pollinator_r pollinator_i pollinator_l pollinator_m pollinator_z
#> plnt_n 1 0 0 0 0
#> plnt_d 0 1 0 0 0
#> plnt_g 0 0 1 0 0
#> plnt_v 0 0 0 1 0
#> plnt_y 0 0 0 0 1
#> plnt_l 0 0 0 0 0
#> plnt_r 0 0 0 0 0
#> plnt_j 0 0 0 0 0
#> pollinator_k pollinator_o pollinator_c pollinator_j pollinator_x
#> plnt_n 0 0 0 0 0
#> plnt_d 0 0 0 0 0
#> plnt_g 0 0 0 0 0
#> plnt_v 0 0 1 0 0
#> plnt_y 0 0 0 0 0
#> plnt_l 1 0 0 0 1
#> plnt_r 0 1 0 0 0
#> plnt_j 0 0 0 1 0
#>
#> [[5]]
#> pollinator_l pollinator_p pollinator_f pollinator_x pollinator_m
#> plnt_m 1 0 0 1 0
#> plnt_i 0 1 0 0 0
#> plnt_x 0 0 1 0 0
#> plnt_k 0 0 0 0 1
#> plnt_l 0 0 0 0 0
#> plnt_z 0 0 0 0 0
#> pollinator_u pollinator_e pollinator_r pollinator_b pollinator_a
#> plnt_m 0 0 0 0 0
#> plnt_i 0 0 1 0 1
#> plnt_x 1 0 0 0 0
#> plnt_k 0 0 0 0 0
#> plnt_l 0 1 0 0 0
#> plnt_z 0 0 0 1 0
#>
#> [[6]]
#> pollinator_d pollinator_x pollinator_n pollinator_y pollinator_s
#> plnt_k 1 0 0 0 0
#> plnt_b 0 1 0 0 0
#> plnt_m 0 0 1 0 0
#> plnt_g 0 0 0 1 0
#> plnt_z 0 0 0 0 1
#> plnt_j 0 0 0 0 0
#> plnt_x 0 0 0 0 0
#> plnt_v 0 0 0 0 0
#> pollinator_k pollinator_i pollinator_c
#> plnt_k 0 0 0
#> plnt_b 0 0 0
#> plnt_m 1 0 0
#> plnt_g 0 0 0
#> plnt_z 0 0 0
#> plnt_j 1 0 0
#> plnt_x 0 1 0
#> plnt_v 0 0 1
#>
#> [[7]]
#> pollinator_r pollinator_x pollinator_k pollinator_j pollinator_u
#> plnt_q 1 0 0 0 0
#> plnt_o 0 1 0 0 0
#> plnt_z 0 0 1 0 0
#> plnt_t 0 1 0 0 0
#> plnt_g 0 0 0 1 0
#> plnt_e 0 0 0 0 1
#> plnt_p 0 0 0 0 1
#> plnt_r 0 0 0 0 0
#> plnt_n 0 0 0 0 0
#> pollinator_a pollinator_s pollinator_d
#> plnt_q 0 0 0
#> plnt_o 0 0 1
#> plnt_z 0 0 0
#> plnt_t 0 0 0
#> plnt_g 0 0 0
#> plnt_e 0 0 0
#> plnt_p 0 0 0
#> plnt_r 1 0 0
#> plnt_n 0 1 0
#>
#> [[8]]
#> pollinator_g pollinator_b pollinator_m pollinator_v pollinator_c
#> plnt_w 1 0 0 1 0
#> plnt_l 0 1 0 0 0
#> plnt_s 0 0 1 0 0
#> plnt_c 0 0 0 1 0
#> plnt_p 0 0 0 0 1
#> plnt_x 0 0 0 0 0
#> plnt_d 0 0 0 0 0
#> plnt_r 0 0 0 0 0
#> pollinator_o pollinator_z pollinator_t pollinator_j
#> plnt_w 0 0 0 0
#> plnt_l 0 0 0 0
#> plnt_s 0 0 0 0
#> plnt_c 0 0 0 1
#> plnt_p 0 0 0 0
#> plnt_x 1 0 0 0
#> plnt_d 0 1 0 0
#> plnt_r 0 0 1 0
#>
#> [[9]]
#> pollinator_g pollinator_x pollinator_f pollinator_v pollinator_q
#> plnt_t 1 0 0 0 0
#> plnt_k 0 1 0 0 0
#> plnt_l 0 0 1 0 0
#> plnt_r 0 0 0 1 0
#> plnt_b 0 0 0 0 1
#> plnt_s 0 0 0 0 0
#> plnt_m 0 0 0 0 0
#> plnt_n 0 0 1 0 0
#> plnt_g 0 0 0 0 0
#> pollinator_z pollinator_e pollinator_n pollinator_w
#> plnt_t 0 0 0 0
#> plnt_k 0 0 0 0
#> plnt_l 1 0 0 0
#> plnt_r 0 0 0 0
#> plnt_b 0 0 0 0
#> plnt_s 0 1 0 0
#> plnt_m 0 0 1 0
#> plnt_n 0 0 0 0
#> plnt_g 0 0 0 1
#>
#> [[10]]
#> pollinator_i pollinator_q pollinator_g pollinator_b pollinator_p
#> plnt_p 1 0 0 0 0
#> plnt_h 0 1 0 0 0
#> plnt_y 0 0 1 0 0
#> plnt_s 0 0 0 1 0
#> plnt_z 0 0 0 0 1
#> plnt_j 0 0 0 0 0
#> plnt_e 0 0 0 0 0
#> plnt_m 0 0 0 0 0
#> plnt_x 0 0 0 0 0
#> pollinator_o pollinator_z pollinator_a pollinator_y pollinator_h
#> plnt_p 0 0 0 0 0
#> plnt_h 0 0 0 0 0
#> plnt_y 0 0 0 0 0
#> plnt_s 0 0 0 0 0
#> plnt_z 0 0 0 0 0
#> plnt_j 1 1 0 0 0
#> plnt_e 0 0 1 0 0
#> plnt_m 0 0 0 1 0
#> plnt_x 0 0 0 0 1
<sup>Created on 2023-02-19 with reprex v2.0.2</sup>
答案2
得分: 2
避免使用 igraph
,使用 table()
。
## from question.
set.seed(75498353)
n <- 10 # 植物和传粉者的数量。
network_list <- replicate(2, expr = {
data.frame( plant = paste('plnt', '_', sample(x = letters, size = n, replace = TRUE), sep = ""),
pollinator = paste('pollinator', '_', sample(x = letters, size = n, replace = TRUE), sep = "")
)
}, simplify = FALSE)
## 创建关联矩阵的列表。
incidence_list <- lapply(network_list, table)
incidence_list
注意:代码部分不翻译。
英文:
Avoid igraph
and use table()
.
## from question.
set.seed(75498353)
n <- 10 # size of plant, pollinator.
network_list <- replicate(2, expr = {
data.frame( plant = paste('plnt', '_', sample(x = letters, size = n, replace = TRUE), sep = ""),
pollinator = paste('pollinator', '_', sample(x = letters, size = n, replace = TRUE), sep = "")
)
}, simplify = FALSE)
## create list of incidence matrices.
incidence_list <- lapply(network_list, table)
incidence_list
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论