igraph R中图连通分量的顶点条件标记及数据框转换需求
解决方案
思路分析
根据需求,我们以**入度为2的节点(路径终止于其之前)和出度为2的节点(路径终止于此)**作为分割点,从每个入度为0的源节点开始追踪路径,给同一路径上的节点分配相同前缀的标签,最终得到7个目标标签。
完整代码实现
library(igraph) # 构建图数据 df <- structure(list(from = c("A1", "A2", "A3", "A4", "B1", "B2", "B3", "C1", "C2", "C3", "E1", "E2", "E3", "F1", "F2", "D1", "E3", "G1", "G2", "G3"), to = c("A2", "A3", "A4", "C1", "B2", "B3", "C1", "C2", "C3", "D1", "E2", "E3", "F1", "F2", "D1", "D2", "G1", "G2", "G3", "G4")), class = "data.frame", row.names = c(NA, -20L)) g <- graph_from_data_frame(df) # 1. 识别分割节点:入度为2的节点、出度为2的节点 split_nodes <- c( V(g)[degree(g, mode = "in") == 2]$name, V(g)[degree(g, mode = "out") == 2]$name ) # 2. 初始化结果数据框 result_df <- data.frame(vertex = character(), label = character(), stringsAsFactors = FALSE) # 3. 处理入度为0的源节点路径 source_nodes <- V(g)[degree(g, mode = "in") == 0]$name for (source in source_nodes) { current_node <- source current_path <- c(current_node) while (TRUE) { next_nodes <- neighbors(g, current_node, mode = "out")$name if (length(next_nodes) == 0) break next_node <- next_nodes[1] # 判断下一个节点是否为分割点 if (next_node %in% split_nodes) { # 出度为2的节点,将其加入当前路径后终止 if (degree(g, next_node, mode = "out") == 2) { current_path <- c(current_path, next_node) } break } current_path <- c(current_path, next_node) current_node <- next_node } # 提取节点前缀作为标签 label <- substr(source, 1, 1) result_df <- rbind(result_df, data.frame(vertex = current_path, label = label)) } # 4. 处理非源节点的起始路径(C1、D1) # 处理C1路径 current_node <- "C1" current_path <- c(current_node) while (TRUE) { next_nodes <- neighbors(g, current_node, mode = "out")$name if (length(next_nodes) == 0 || next_nodes[1] %in% split_nodes) break current_path <- c(current_path, next_nodes[1]) current_node <- next_nodes[1] } result_df <- rbind(result_df, data.frame(vertex = current_path, label = "C")) # 处理D1路径 current_node <- "D1" current_path <- c(current_node) next_nodes <- neighbors(g, current_node, mode = "out")$name if (length(next_nodes) > 0) { current_path <- c(current_path, next_nodes[1]) } result_df <- rbind(result_df, data.frame(vertex = current_path, label = "D")) # 查看最终结果 print(result_df)
结果说明
运行代码后得到的result_df包含所有顶点及其对应标签,共7个标签(A、B、C、D、E、F、G),完全符合预期:
- A标签:A1、A2、A3、A4
- B标签:B1、B2、B3
- C标签:C1、C2、C3
- D标签:D1、D2
- E标签:E1、E2、E3
- F标签:F1、F2
- G标签:G1、G2、G3、G4
内容的提问来源于stack exchange,提问作者ahmathelte
相关产品推荐
相关产品推荐

