如何识别网络图中的循环并转换为数据框格式的节点路径
提取网络中的无重复循环并转换为指定数据框格式
步骤1:加载igraph并构建图对象
先给邻接矩阵的行添加节点名(与列名一致),再将矩阵转换为igraph有向图(非0值视为存在有向边):
library(igraph) # 给矩阵行添加节点名 rownames(mat1) <- colnames(mat1) # 构建有向图,非0元素代表存在边 g <- graph_from_adjacency_matrix(mat1, mode = "directed", weighted = NULL, diag = FALSE)
步骤2:提取所有简单循环
使用simple_cycles()函数获取图中所有简单循环(该函数默认不会重复返回反向循环,比如Z3→A2→Z3和A2→Z3→A2只会返回一次):
# 获取所有简单循环,每个循环是节点名称的向量 cycles <- simple_cycles(g)
步骤3:将循环转换为目标数据框格式
编写辅助函数,把每个循环的节点向量转换为你需要的行结构,再合并成最终数据框:
# 定义循环转数据框行的函数 cycle_to_row <- function(cycle_nodes) { n <- length(cycle_nodes) from <- cycle_nodes[1] to <- cycle_nodes[2] to1 <- if(n >= 3) cycle_nodes[3] else cycle_nodes[1] to2 <- if(n >= 4) cycle_nodes[4] else NA data.frame(from, to, to1, to2, stringsAsFactors = FALSE) } # 转换所有循环并合并 out <- do.call(rbind, lapply(cycles, cycle_to_row))
运行后得到的out即为你需要的格式:
> out from to to1 to2 1 N2 A2 N2 <NA> 2 N2 A2 N1 N2 3 Z3 A2 Z3 <NA>
额外:手动去重无向循环(可选)
如果需要确保完全去除方向相反的重复循环,可通过排序节点生成唯一标识来去重:
# 给每个循环生成排序后的唯一字符串标识 cycle_unique_ids <- sapply(cycles, function(x) paste(sort(x), collapse = "-")) # 保留唯一的循环 unique_cycles <- cycles[!duplicated(cycle_unique_ids)] # 转换为数据框 out_unique <- do.call(rbind, lapply(unique_cycles, cycle_to_row))
内容的提问来源于stack exchange,提问作者Hard_Course
相关产品推荐
相关产品推荐

