使用ggalluvial绘制桑基图报错:数据非可识别冲积格式
解决方案:修复ggalluvial桑基图报错问题
错误原因分析
你的核心问题在于数据处理流程冗余且格式转换错误:
- 原始数据已经是ggalluvial要求的「lodes格式」(每行对应一个学生的单年度成绩分位数),无需额外用
to_lodes_form()转换 group_by()+summarise()生成的Freq列反而破坏了数据结构,导致geom_flow()无法识别合法的冲积层数据
修正后的代码(两种可选方案)
方案1:直接用原始长数据绘图(推荐)
library(ggplot2) library(ggalluvial) library(dplyr) # 数据加载 data <- read.csv("/mydata.csv") # 转换为有序因子(确保分位数/学年顺序正确) data$Year <- factor(data$Year, levels = c("A1", "A2", "A3")) data$Quintile <- factor(data$Quintile, levels = as.character(1:5)) data$Student_ID <- factor(data$Student_ID) # 去重(确保每个学生每年只有一条记录) data <- data %>% distinct(Student_ID, Year, .keep_all = TRUE) # 绘制桑基图 ggplot(data, aes(x = Year, stratum = Quintile, alluvium = Student_ID, fill = Quintile)) + geom_flow(stat = "alluvium", lode.guidance = "rightleft", color = "darkgray") + geom_stratum() + geom_text(stat = "stratum", aes(label = after_stat(stratum))) + scale_x_discrete(limits = c("A1", "A2", "A3")) + scale_fill_viridis_d(option = "plasma") # 可选:更美观的分位数配色 theme_minimal() + labs(title = "学生成绩分位数年度变化", x = "学年", y = "学生人数", fill = "成绩分位数")
方案2:转换为宽格式绘图(适合关注转移频数场景)
如果需要聚焦不同分位数区间的转移人数,可以先转宽格式再统计频数:
library(ggplot2) library(ggalluvial) library(dplyr) library(tidyr) # 数据加载与预处理(同方案1) data <- read.csv("/mydata.csv") data$Year <- factor(data$Year, levels = c("A1", "A2", "A3")) data$Quintile <- factor(data$Quintile, levels = as.character(1:5)) data <- data %>% distinct(Student_ID, Year, .keep_all = TRUE) # 转换为宽格式(每列对应一个学年的分位数) data_wide <- data %>% select(Student_ID, Year, Quintile) %>% pivot_wider(names_from = Year, values_from = Quintile) # 统计各分位数组合的学生数 data_trans <- data_wide %>% count(A1, A2, A3, name = "Freq") # 绘制桑基图 ggplot(data_trans, aes(y = Freq, axis1 = A1, axis2 = A2, axis3 = A3)) + geom_alluvium(aes(fill = A1), width = 1/12) + geom_stratum(width = 1/12, color = "black") + geom_text(stat = "stratum", aes(label = after_stat(stratum))) + scale_x_discrete(limits = c("A1", "A2", "A3"), expand = c(0.05, 0.05)) + scale_fill_brewer(palette = "Set2") + theme_minimal() + labs(title = "学生成绩分位数年度转移", x = "学年", y = "学生人数", fill = "初始分位数(A1)")
额外排查要点
- 检查数据完整性:用
data %>% group_by(Student_ID) %>% filter(n() != 3)找出缺少某年度成绩的学生,这类数据会导致冲积层连接中断 - 确保因子顺序正确:分位数和学年必须指定
levels,否则绘图会出现乱序 - 避免重复映射:全局
aes()已经包含fill=Quintile,无需在geom_flow()中重复声明
内容的提问来源于stack exchange,提问作者Augustin Gaudemer
相关产品推荐
相关产品推荐

