igraph实现每条边中点添加新节点并赋予平均海拔属性
为igraph图的每条边中点添加新节点并设置属性
我有一个igraph图,其中每个节点和边都具备独立属性(例如节点拥有不同海拔,边拥有不同直径和长度)。现在需要在每条边的中点添加新节点,并将该新节点的海拔设为其连接的两个节点的平均海拔,希望通过循环实现以适配节点和边数量较多的大型网络。
示例图加载与属性设置
方式1:从RDS文件加载
如果已有g.rds文件,可通过以下代码加载:
library(igraph) g = readRDS("g.rds") plot(g)
方式2:直接构建示例图
若没有g.rds,可使用以下代码构建包含属性的示例图:
library(igraph) # 从dput结构构建图 g <- structure(list(4, FALSE, c(3, 2, 2, 1), c(0, 0, 1, 0), c(3, 1, 2, 0), c(3, 1, 0, 2), c(0, 0, 1, 3, 4), c(0, 3, 4, 4, 4), list( c(1, 0, 1), structure(list(), names = character(0)), list( name = c("J-1", "J-2", "J-3", "R-1"), XCoord = c(1248.164, 5991.189, 2246.696, -631.424), YCoord = c(5976.505, 5741.557, 3113.069, 7621.145), color = c("gray", "gray", "gray", "orange"), shape = c("circle", "circle", "circle", "square" ), elevation = c(10L, 50L, 30L, 10L), Elevation = c(10L, 50L, 30L, 30L)), list(label = c("P-1", "P-2", "P-3", "P-4"), Diameter = c(500L, 500L, 500L, 500L), Lenght = c(1000L, 1000L, 1000L, 1000L), label_no_P = c(1, 2, 3, 4), Length = c(1000L, 1000L, 1000L, 1000L))), environment(), class = "igraph") # 确保属性正确(若构建后属性缺失可重新设置) E(g)$Length = c(1000, 1000, 1000, 1000) E(g)$Diameter = c(500, 500, 500, 500) V(g)$Elevation = c(10, 50, 30, 30)
解决方案:循环添加中点节点
以下代码通过循环遍历每条边,完成中点节点的添加与属性设置,适配大型网络:
# 复制原图避免修改原数据 g_new <- g # 获取边的数量 edge_count <- ecount(g_new) # 倒序遍历边,避免删除边后索引错乱 for (i in rev(1:edge_count)) { # 获取当前边的两端节点 endpoints <- ends(g_new, i) node1 <- endpoints[1] node2 <- endpoints[2] # 计算两端节点的平均海拔 avg_elevation <- mean(c(V(g_new)$Elevation[node1], V(g_new)$Elevation[node2])) # 添加新节点并设置属性 new_node_id <- add_vertices(g_new, 1, name = paste0("Mid-", i), Elevation = avg_elevation, color = "blue", # 可选:设置新节点颜色方便区分 shape = "triangle") # 删除原边 g_new <- delete_edges(g_new, i) # 添加两条新边,继承原边的属性 g_new <- add_edges(g_new, c(node1, new_node_id, node2, new_node_id), attr = list( Length = E(g)$Length[i], Diameter = E(g)$Diameter[i], label = paste0("P-", i, "-1"), label_no_P = paste0(i, "-1") )) } # 查看处理后的图 plot(g_new) # 检查新节点的海拔属性 print(V(g_new)$Elevation)
代码说明
- 倒序遍历边:删除原边会改变后续边的索引,倒序遍历可避免索引错乱问题。
- 新节点属性:除海拔外,可自定义颜色、形状等属性,方便区分新节点与原节点。
- 边属性继承:将原边的长度、直径等属性传递给新边,保留原有边的属性信息。
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

