You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ggsankeyfier制作y轴为分类变量的桑基图及优化问题

桑基图优化方案(基于ggsankeyfier)

问题描述

使用ggsankeyfier绘制客户年度类别流动桑基图时,遇到两个问题:

  • 需手动创建冗余的final_class变量
  • 节点默认升序排列,希望按class顺序(0在底部、3在顶部)排列,但设置y=node会丢失节点宽度

优化方案及代码

核心优化思路

  1. 移除冗余变量:利用ggsankeyfier的统计层自动计算节点权重,无需手动构造final_class
  2. 自定义节点排序:将class转换为有序因子,强制节点按指定顺序排列,同时保留节点宽度

完整优化代码:

library(tidyverse)
library(ggsankeyfier)

# 生成示例数据
t <- data.frame(
  client = rep(c('a','b','c','d','e','f','g'), each = 4), 
  year = rep(2021:2024,7), 
  class = sample(0:3, size = 28, replace = T, prob = c(0.6,0.3,0.09,0.1))
)

# 数据预处理:转宽表+将class转为有序因子(控制排序)
t_wide <- t %>%
  pivot_wider(names_from = year, values_from = class) %>%
  mutate(across(2021:2024, ~ factor(.x, levels = c(0,1,2,3), ordered = TRUE)))

# 绘制桑基图
ggplot(t_wide) +
  aes(
    x = stage, 
    y = after_stat(weight),  # 自动用客户数量作为节点权重,替代final_class
    group = node, 
    connector = connector, 
    edge_id = edge_id
  ) +
  pivot_stages_longer(as.character(2021:2024)) +  # 无需指定values_from参数
  geom_sankeyedge(aes(fill = node), position = pos, ncp = 1) +
  geom_sankeynode(aes(fill = node), position = pos) +
  geom_text(
    aes(label = str_wrap(node, 20)), 
    position = pos_text, 
    stat = "sankeynode",
    hjust = 0, 
    cex = 2
  ) +
  theme_minimal()

关键细节说明

  • 移除冗余变量:通过y = after_stat(weight)让stat_sankeynode自动计算节点高度(对应客户数量),完全替代手动创建的final_class变量,简化数据处理步骤
  • 节点排序控制:将各年度的class列转为有序因子,指定levels = c(0,1,2,3),这样绘图时节点会严格按照0(底部)→1→2→3(顶部)的顺序排列,同时节点宽度由对应客户数量自动计算,不会丢失宽度信息

内容的提问来源于stack exchange,提问作者Théodore Targerian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:55:00