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

如何在ggalluvial中实现多流汇聚至同一节点分区的桑基图绘制?

用ggalluvial实现多流汇聚到同一节点分区的方法

要让多个上游节点的流汇聚到下游同一个节点分区,核心是利用ggalluvial中alluvium参数的“轨迹跟踪”特性——它用来标识每一条流动的“实体/分组”,只要把需要合并的流归到同一个alluvium分组,或者让不同上游实体的下游轨迹指向同一个目标分区,就能实现汇聚效果。下面我分两种场景给你具体代码和解释:

场景1:基于个体级数据的汇聚(最直观)

如果你的数据是每个样本(比如用户、受试者)的时间序列记录,直接修改样本在下游节点的分类即可:

library(ggalluvial)
set.seed(123) # 固定随机数保证结果一致

# 构造模拟数据:50个受试者的3次调查响应
# Time1:20人选always,15人选sometimes,15人选never
time1 <- data.frame(
  survey = "Time1",
  subject = 1:50,
  response = c(rep("always",20), rep("sometimes",15), rep("never",15)),
  freq = 1
)
# Time2:让Time1的always和sometimes全部转为always,never保持不变
time2 <- data.frame(
  survey = "Time2",
  subject = 1:50,
  response = c(rep("always",35), rep("never",15)),
  freq = 1
)
# Time3:保持Time2的响应结果
time3 <- data.frame(
  survey = "Time3",
  subject = 1:50,
  response = c(rep("always",35), rep("never",15)),
  freq = 1
)

# 合并数据并整理因子顺序
combined_data <- rbind(time1, time2, time3)
combined_data$response <- factor(combined_data$response, levels = c("always", "sometimes", "never"))

# 绘制桑基图
ggplot(combined_data, aes(
  x = survey, 
  stratum = response, 
  alluvium = subject, # 用subject跟踪每个个体的流动轨迹
  y = freq, 
  fill = response, 
  label = response
)) +
  scale_x_discrete(expand = c(.1, .1)) +
  geom_flow() + # 流会自动汇聚到对应的下游分区
  geom_stratum(alpha = .5) +
  geom_text(stat = "stratum", size = 3) +
  theme(legend.position = "right") +
  ggtitle("多流汇聚效果:Time1的always+sometimes → Time2的always")

运行后你会看到:Time1的always和sometimes两条流,全部汇聚到Time2的always节点分区里,完美实现你要的效果。

场景2:基于汇总数据的汇聚(适合大样本)

如果你的数据已经是汇总后的频率值,不需要个体记录,可以手动指定alluvium分组来关联需要合并的流:

library(ggalluvial)
library(dplyr)

# 构造汇总数据:注意下游节点的频率是上游流入频率之和
summary_data <- data.frame(
  survey = rep(c("Time1", "Time2", "Time3"), each = 3),
  response = rep(c("always", "sometimes", "never"), 3),
  freq = c(20,15,15, 35,0,15, 35,0,15) # Time2的always=20+15=35
)

# 关键:给需要合并的流指定同一个alluvium分组
summary_data <- summary_data %>%
  mutate(alluvium = case_when(
    # Time1的always和sometimes都归为group1,对应下游的always
    (survey == "Time1" & response %in% c("always", "sometimes")) | 
    (survey %in% c("Time2","Time3") & response == "always") ~ "group1",
    # never的流单独归为group2
    survey %in% c("Time1","Time2","Time3") & response == "never" ~ "group2",
    TRUE ~ NA_character_
  ))

# 绘图
ggplot(summary_data, aes(
  x = survey, 
  stratum = response, 
  alluvium = alluvium, # 用分组标识跟踪流的汇聚
  y = freq, 
  fill = response, 
  label = response
)) +
  scale_x_discrete(expand = c(.1, .1)) +
  geom_flow() +
  geom_stratum(alpha = .5) +
  geom_text(stat = "stratum", size = 3) +
  theme(legend.position = "right") +
  ggtitle("汇总版多流汇聚桑基图")

核心原理总结

  1. alluvium是关键:它相当于每条流的“身份证”,只要两个上游流的alluvium在下游指向同一个stratum(分区),它们就会自动汇聚。
  2. 频率要匹配:下游目标分区的频率必须等于所有流入它的上游分区频率之和,否则节点块大小会出现断层。
  3. 两种场景任选:个体级数据更直观,汇总级数据更高效,根据你的原始数据类型选择即可。

内容的提问来源于stack exchange,提问作者userq8957289475

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:22:38