igraph/tidygraph中sf_network子边值求和异常问题排查
问题描述
我拥有一个sf_network对象,希望对每条边的值进行求和,使根边的值等于所有其他边的值之和。以下是我用于测试的示例代码:
#Testing Data tree_t <- create_tree(20, 3) |> mutate(leaf = node_is_leaf()) iris_tree <- tree_t %>% morph(to_linegraph) %>% #Morphing to convert edges to nodes activate(nodes) %>% mutate(value_2_sum = 1) |> mutate(summed_value = map_bfs_back_dbl(node_is_root(), .f = function(node, path, ...) { nodes <- .N() if (is.null(nodes$leaf[node])) return(sum(nodes[path$node,]$value_2_sum,nodes$value_2_sum[node],na.rm = T)) return(sum(path$result[[1]],nodes$value_2_sum[node],na.rm=T)) #Problem with the logic here I think. })) |> unmorph() #Plot ggraph(iris_tree) + geom_edge_diagonal2(aes(colour = summed_value, label = summed_value)) + theme_graph()
从绘制的图表中可见,多数边的值已正确累加,但图表左上角的4条边未正确统计下方边的值。我推测问题出在第二个return语句的path$result调用上,希望得到解决思路。
解决思路
- 子节点结果只取第一个导致遗漏:
path$result是存储所有子节点计算结果的列表,你用path$result[[1]]只提取了第一个子节点的结果,当节点存在多个子节点时,会漏掉其他子节点的求和值,应该对整个path$result列表的所有元素求和。 - 叶子节点判断逻辑不匹配:线图的节点对应原树的边,原树的
leaf字段是原节点的属性,用来判断线图节点是否为叶子完全不匹配。正确做法是在线图中,直接用node_is_leaf()判断当前节点是否没有子节点。
修正后的代码
#Testing Data tree_t <- create_tree(20, 3) |> mutate(leaf = node_is_leaf()) iris_tree <- tree_t %>% morph(to_linegraph) %>% activate(nodes) %>% mutate(value_2_sum = 1) |> mutate(summed_value = map_bfs_back_dbl(node_is_root(), .f = function(node, path, ...) { # 在线图中判断当前节点是否为叶子(无后续子节点) is_leaf <- node_is_leaf(node) if (is_leaf) { # 叶子节点直接返回自身的value_2_sum return(.N()$value_2_sum[node]) } else { # 非叶子节点:所有子节点的summed_value之和 + 自身value_2_sum child_sums <- if (length(path$result) > 0) sum(unlist(path$result), na.rm = TRUE) else 0 return(child_sums + .N()$value_2_sum[node]) } })) |> unmorph() #Plot ggraph(iris_tree) + geom_edge_diagonal2(aes(colour = summed_value, label = summed_value)) + theme_graph()
内容的提问来源于stack exchange,提问作者CCurtis
相关产品推荐
相关产品推荐

