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

使用ggalluvial/ggsankey库处理缺失组合与脱落病例的绘图问题

问题需求

需要展示3个不同年份治疗组间的患者流动情况,数据存在脱落/新增患者:部分患者在后续年份缺失,或后续年份出现新患者,用"none"标记这些缺失组合。希望使用geom_sankey绘制桑基图时,保留正常的患者流动连线(冲积流),但隐藏标注为"none"或NA的分层节点。

解决方案

核心思路是预处理数据,过滤掉无效的"none"/NA节点,仅保留患者的有效流动路径,再生成桑基图数据。

步骤1:数据预处理

先将原始数据中的"none"统一替换为NA,再转换为宽格式:

library(tidyverse)
library(ggsankey)

# 合并年份数据并预处理
data <- bind_rows(data_2015, data_2017, data_2019) %>% 
  select(sip, Year, Grp) %>%
  # 将"none"替换为NA,统一缺失值标记
  mutate(Grp = ifelse(Grp == "none", NA, as.character(Grp))) %>%
  mutate(Grp = factor(Grp), Year = factor(Year)) %>%
  arrange(sip) %>% 
  # 转换为宽格式:每一行是一个患者的三年分组情况
  pivot_wider(names_from = Year, values_from = Grp)

步骤2:生成有效流动路径

提取每个患者的非NA分组记录,跳过缺失年份,直接连接前后有效分组:

# 处理每个患者的有效路径,跳过NA节点
df_sankey <- data %>%
  rowwise() %>%
  # 提取当前患者的非NA(年份,分组)对
  mutate(valid_path = list(
    na.omit(tibble(
      year = c(`2015`, `2017`, `2019`),
      grp = c(`2015`, `2017`, `2019`)
    ))
  )) %>%
  ungroup() %>%
  unnest(valid_path) %>%
  # 为每个路径节点生成下一个节点信息
  group_by(sip) %>%
  mutate(
    next_year = lead(year),
    next_grp = lead(grp)
  ) %>%
  # 过滤掉没有后续节点的行(每个患者的最后一个有效节点)
  drop_na(next_year, next_grp) %>%
  ungroup() %>%
  # 重命名为ggsankey要求的列名格式
  rename(
    x = year,
    node = grp,
    next_x = next_year,
    next_node = next_grp
  ) %>%
  # 确保年份顺序正确
  mutate(
    x = factor(x, levels = c("2015", "2017", "2019")),
    next_x = factor(next_x, levels = c("2015", "2017", "2019"))
  )

步骤3:绘制桑基图

使用处理后的有效路径数据绘图,此时不会出现NA/"none"的节点:

ggplot(df_sankey, aes(
  x = x, 
  next_x = next_x, 
  node = node, 
  next_node = next_node,
  fill = factor(node),
  label = node,
  color = factor(node)
)) +
  geom_sankey(flow.alpha = 0.5, node.color = 1) +
  geom_sankey_label(size = 3.5, color = 1, fill = "white") +
  scale_fill_viridis_d() +
  scale_colour_viridis_d() +
  theme_sankey(base_size = 16) +
  theme(legend.position = "none") + 
  xlab("")

说明

  • 该方法会自动跳过患者的缺失年份,直接连接前后有效治疗组的流动,同时完全隐藏无效的"none"/NA节点。
  • 如果需要保留缺失年份的间隔(比如2015到2019的流动线跨过年份2017的位置),上述代码会自动处理,流动线会在对应的年份位置之间绘制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:46:07