如何在R中用networkD3的sankeyNetwork控制桑基图节点所属列
解决方案
networkD3的sankeyNetwork()默认会根据流的连接关系自动计算节点的层级位置,要手动固定节点所在的列,你可以通过给节点数据框添加自定义坐标列+禁用自动布局迭代实现,操作步骤如下:
- 给
nodes数据框添加x列,指定每个节点的列位置(从0开始计数,你要的第一列对应0,第二列对应1,第三列对应2) - 可选添加
y列指定节点的垂直排序,也可以先运行一次默认绘图提取自动计算的y值使用 - 调用
sankeyNetwork()时添加iterations = 0参数,禁用自动布局算法,使用你自定义的坐标
完整可运行代码如下:
library(networkD3) links <- data.frame(source=c("1_a", "1_b", "1_c", "2_b", "2_d"), target=c("2_a", "2_b", "2_c", "3_a", "3_b"), value=c(3,2,5,4,7)) nodes <- data.frame(name=c("1_a", "1_b", "1_c", "2_b", "2_d", "2_a", "2_c", "3_a", "3_b")) # 手动指定节点所在列:第一列(x=0)放1开头的节点,第二列(x=1)放2开头的,第三列(x=2)放3开头的 nodes$x <- c(0,0,0,1,1,1,1,2,2) # 手动指定垂直顺序,可根据自己的需求调整 nodes$y <- c(0,1,2,1,3,0,2,0,1) links$IDsource <- match(links$source, nodes$name)-1 links$IDtarget <- match(links$target, nodes$name)-1 # 绘图时添加iterations=0参数,禁用自动布局 sankeyNetwork(Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget", Value = "value", NodeID = "name", iterations = 0, sinksRight = FALSE)
如果你不想手动调整y坐标,可以先运行一次不带iterations = 0的绘图,提取自动计算的y值复用,保证垂直位置是算法优化过的无重叠效果:
# 先运行默认绘图获取自动计算的坐标 p <- sankeyNetwork(Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget", Value = "value", NodeID = "name", sinksRight = FALSE) # 提取自动计算的y值 y_vals <- unlist(lapply(p$x$nodes, function(x) x$y)) nodes$y <- y_vals # 再用自定义x和自动y重新绘制 p_final <- sankeyNetwork(Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget", Value = "value", NodeID = "name", iterations = 0, sinksRight = FALSE)
内容的提问来源于stack exchange,提问作者matnor
相关产品推荐
相关产品推荐

