如何按各分组累计值调整ggplot堆叠条形图的堆叠顺序
问题原因
你当前代码中使用reorder(subgroup, value)是基于全数据集的value值为subgroup生成全局统一的因子顺序,ggplot2的堆叠条形图默认遵循全局因子顺序排列所有条形的堆叠层级,因此无法实现不同x分组下独立的子组堆叠顺序。
实现方法
核心逻辑是先按大组分组,计算每个大组内部各子组的累计值,按累计值为每个大组内的子组排序,再生成独立的分组标识映射到geom_col的group美学,打破全局统一的堆叠顺序限制,同时保留fill映射到原子组保证同子组颜色一致。
library(ggplot2) library(dplyr) set.seed(8) # 构造示例数据 name <- c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z", "aa") group <- c("1","1","1","2","2", "2", "1","1","1","1","1","1","1","1","1","1","1","1","2","2","2","2","2","2","2","2") subgroup <- c("C", "C", "C", "C", "C", "C", "A", "A", "A","A","A","A","B","B","B","B","B","B","B","B", "C", "C", "C", "C", "C", "C") value <- runif(26, min = 0, max = 10) df <- data.frame(name, group, subgroup,value) # 数据预处理 df <- df %>% group_by(group, subgroup) %>% # 计算每个大组内各子组的累计值 mutate(subg_sum = sum(value)) %>% ungroup() %>% # 按大组、子组累计值升序排列,决定从下到上的堆叠顺序 arrange(group, subg_sum) %>% # 生成唯一的堆叠分组标识,因子顺序与排序结果一致 mutate(stack_id = factor(paste0(group, "_", subgroup), levels = unique(paste0(group, "_", subgroup)))) # 绘图 ggplot(df, aes(x = group, y = value)) + geom_col( aes(fill = subgroup, group = stack_id), color = "white" # 可选:添加白色边界区分相邻堆叠块 )
效果说明
- 大组1内子组累计值从小到大依次为:C(17.8) < A(30.2) < B(40.8),堆叠顺序从下到上和该顺序完全一致
- 大组2内子组累计值从小到大依次为:B(10.6) < C(43.1),堆叠顺序同样匹配组内排序结果
- 如果需要将累计值更大的子组放在堆叠底层,只需要将
arrange(group, subg_sum)修改为arrange(group, desc(subg_sum))即可。
内容的提问来源于stack exchange,提问作者Andres Gonzalez
相关产品推荐
相关产品推荐

