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

如何在ggplot桑基图第二节点添加来自第一节点的患者占比

在桑基图第二节点添加来自第一节点的细分占比标签

1. 预处理数据,计算细分占比

先统计每个Method_Group到Topic的流量频数,再计算每个Topic下各来源的占比,最后拼接成需要的多层标签文本:

library(dplyr)

# 统计各Method_Group到Topic的流量次数
flow_counts <- df2 %>%
  filter(x == "Method_Group") %>%
  count(node, next_node, name = "flow_n")

# 统计每个Topic的总频数,以及其在整体中的占比
topic_totals <- flow_counts %>%
  group_by(next_node) %>%
  summarise(
    total_n = sum(flow_n),
    overall_pct = scales::percent(total_n / sum(flow_counts$flow_n), accuracy = 0.1)
  )

# 合并数据,计算每个来源在对应Topic中的占比,并生成标签文本
topic_labels <- flow_counts %>%
  left_join(topic_totals, by = "next_node") %>%
  group_by(next_node) %>%
  mutate(
    source_pct = scales::percent(flow_n / total_n, accuracy = 0.1),
    source_line = paste0("- ", node, ": n=", flow_n, " (", source_pct, ")")
  ) %>%
  summarise(
    label_text = paste0(
      next_node, "\nn=", total_n, " (", overall_pct, ")\n",
      paste(source_line, collapse = "\n")
    )
  )

2. 修改桑基图代码,替换自定义标签

保留原代码中节点分色的逻辑,将第二节点(Topic)的标签替换为我们生成的多层细分占比文本:

library(ggsankey)
library(ggplot2)

width <- .4
p <- ggplot(df2, aes(x = x, next_x = next_x, node = node, next_node = next_node, fill = factor(node), label = node)) +
  geom_sankey(flow.alpha = 1, node.color = "black", show.legend = FALSE, width = width, linewidth = 2) +
  theme_void() +
  theme(
    plot.margin = unit(rep(5.5, 4), "pt")
  ) +
  scale_fill_viridis_d()

# 获取流量和节点层数据(原代码逻辑,用于实现节点分色)
dat <- layer_data(last_plot(), 1) |>
  filter(x ==  2 - width / 2) |>
  distinct(fill, flow_end_ymax, .keep_all = TRUE)

dat1 <- layer_data(last_plot(), 2) |>
  filter(xmin == 2 - width / 2)

# 绘制最终图形,替换第二节点的标签
p +
  geom_rect(data = dat, aes(
    xmin = x, xmax = x + width,
    ymin = flow_end_ymin, ymax = flow_end_ymax,
    fill = label
  ), inherit.aes = FALSE) +
  geom_rect(data = dat1, aes(
    xmin = xmin, xmax = xmax,
    ymin = ymin, ymax = ymax
  ), inherit.aes = FALSE, fill = NA, color = "black", linewidth = 2) +
  # 自定义标签:第二节点用细分占比文本,第一节点保持原标签
  geom_sankey_label(
    aes(label = ifelse(x == "Topic", 
                       topic_labels$label_text[match(node, topic_labels$next_node)], 
                       node)),
    size = 3.5, color = 1, fill = "white"
  ) +
  guides(fill = "none")

效果说明

  • 第二节点(Topic)会显示:节点名称 + 总样本量(整体占比) + 每行对应一个来源Method_Group的样本量(在当前Topic中的占比)
  • 第一节点(Method_Group)保持原标签显示,可自行修改ifelse逻辑调整第一节点的标签格式
  • 若要调整标签字体大小、换行间距,修改label_text的拼接逻辑即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:24:49