使用R的ggforce包绘制含NA值的平行桑基图遇格式问题求助
解决ggforce绘制平行节点桑基图的数据格式与参数问题
核心问题梳理
- 目标:绘制列节点相互平行的桑基图,替代
geom_sankey默认的不对齐样式 - 痛点:无法正确格式化数据以适配
geom_parallel_sets的split、value、fill参数 - 数据特征:包含三列年份数据(
Earlier/Latest/Current),存在NA值
数据预处理修正
gather_set_data已生成x(列名)、id(行标识)、y(年份值),但需先统计每条路径的频次作为value——这是geom_parallel_sets绘制流量宽度的核心依据。
修正步骤:
- 将NA替换为统一标识,避免路径断裂
- 统计每条完整路径的出现次数,作为流量值
library(ggplot2) library(ggforce) library(dplyr) # 原始数据创建与预处理 Years <- data.frame( Earlier = c(rep(2012, 2), 2013, 2014, rep(2015, 2), rep(2018, 2), rep(2022, 2), rep(NA, 31)), Latest = c(rep(2023, 4), rep(2022, 6), rep(2021, 10), rep(2020, 3), rep(2019, 6), rep(2018, 3), rep(2017, 3), rep(2013, 4), rep(NA, 2)), Current = c(rep(2023, 10), rep(2022, 12), rep(2021, 11), rep(2020, 1), rep(NA, 7)) ) %>% # 替换NA为统一标识,避免路径丢失 mutate(across(everything(), ~ifelse(is.na(.), "缺失", .))) %>% # 统计每条路径的频次 count(Earlier, Latest, Current, name = "value") # 转换为ggforce所需格式 Years2 <- gather_set_data(Years, 1:3)
正确参数配置与绘图代码
split:对应转换后的y列(节点类别:年份或缺失)value:对应统计得到的路径频次value,控制桑基条宽度fill:按年份(y)设置独特颜色,契合需求
完整绘图代码:
aw <- 0.1 sp <- 0.1 ggplot(Years2, aes(x = x, id = id, split = y, value = value)) + # 绘制桑基流,按年份填充颜色 geom_parallel_sets(aes(fill = y), alpha = 0.6, axis.width = aw, sep = sp) + # 绘制平行节点轴 geom_parallel_sets_axes(axis.width = aw, sep = sp, fill = "gray90", color = "black") + # 绘制节点标签(年份) geom_parallel_sets_labels(aes(label = y), colour = "black", angle = 0, size = 3, axis.width = aw, sep = sp) + # 修改轴标签为原始列名 scale_x_discrete(labels = c("Earlier", "Latest", "Current")) + # 设置颜色主题,可自定义 scale_fill_viridis_d(option = "plasma", name = "年份") + theme_minimal() + theme( axis.title.x = element_blank(), legend.position = "bottom" )
关键说明
- NA值处理:必须将NA替换为统一类别,否则
gather_set_data会忽略对应行,导致路径不完整 - value参数:
geom_parallel_sets依赖流量值计算条宽,直接用原始行数据会让每条路径权重相同,无法体现真实分布 - 节点对齐:
geom_parallel_sets默认会让同列节点平行排列,数据格式正确即可实现目标效果
内容的提问来源于stack exchange,提问作者Purrsia
相关产品推荐
相关产品推荐

