为igraph对象列表添加顶点type属性并生成二分关联矩阵遇阻
批量处理植物-传粉者二分网络生成关联矩阵(igraph)
问题背景
我有一个包含多个植物-传粉者互作二分网络边列表的列表,想用R的igraph包转换为二分关联矩阵做分析。但给graph_list里的igraph对象添加顶点type属性时出错,而且完整数据集有238个网络、8万+边,不想用for循环。
可复现数据
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) # 提取每个网络的顶点type graph_list <- mapply(c, graph_list, list_type) # 尝试给graph_list添加type属性 incidence_list <- lapply(graph_list, get.incidence) # 执行失败 # 报错信息: # Error in FUN(X[[i]], ...) : Not a graph object
get.incidence需要带type属性的二分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 # 强制重复边值为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。
解决方案
不用for循环,用lapply批量处理每个igraph对象,直接在处理函数内完成type属性添加和关联矩阵生成:
# 定义批量处理函数 process_network <- function(edgelist) { # 生成igraph对象 g <- graph_from_data_frame(edgelist) # 获取二分映射并添加type属性 mapping <- bipartite.mapping(g) V(g)$type <- mapping$type # 生成关联矩阵并处理重复值 inc_mat <- get.incidence(g) inc_mat[inc_mat > 1] <- 1 return(inc_mat) } # 批量处理所有网络 incidence_list <- lapply(network_list, process_network)
代码说明
lapply天然适合处理列表,避免显式for循环,效率更高- 每个网络的处理逻辑封装在函数里,清晰易维护
- 直接从边列表到关联矩阵,无需单独维护
graph_list,减少中间变量
如果需要保留处理后的graph对象,可以调整函数返回值:
process_network_with_graph <- function(edgelist) { g <- graph_from_data_frame(edgelist) mapping <- bipartite.mapping(g) V(g)$type <- mapping$type inc_mat <- get.incidence(g) inc_mat[inc_mat > 1] <- 1 return(list(graph = g, incidence_matrix = inc_mat)) } result_list <- lapply(network_list, process_network_with_graph)
内容的提问来源于stack exchange,提问作者troul
相关产品推荐
相关产品推荐

