如何在R ggplot分组堆叠图中按Yes值排序各面板堆叠条
按Farmtype面板内Choice="Yes"的value值排序分组堆叠图
现有如下数据集与ggplot代码,可生成分组堆叠图,要实现每个Farmtype面板内的堆叠条,根据Choice为“Yes”对应的value值进行升序或降序排序,具体实现方法如下:
原始数据集与代码
df <- data.frame( PPE = c("Gloves", "Gloves", "Masks", "Masks", "Gloves", "Gloves", "Masks", "Masks", "Boots", "Boots","Boots","Boots"), Farmtype = c("Farm1", "Farm2", "Farm2", "Farm1", "Farm2", "Farm1", "Farm2", "Farm1", "Farm2", "Farm1", "Farm2", "Farm1"), Choice = c("Yes", "No", "No", "Yes", "Yes", "No", "Yes", "No", "No", "Yes", "Yes", "No"), value = c(10, 15, 8, 12, 9, 6, 14, 11, 20, 5, 10, 6) ) # 原始分组堆叠图代码 ggplot(df, aes(x = PPE, y = value, fill = Choice)) + geom_bar(stat = "identity", position = "stack") + facet_grid(Farmtype ~ ., switch = "x") + labs(x = "PPE", y = "Value", fill = "Choice") + ggtitle("Grouped and Stacked Graph") + theme_classic()+ coord_flip()
实现分面板排序的解决方案
核心思路是为每个Farmtype单独定义PPE的排序规则,将PPE转换为带有分组排序信息的因子,具体步骤如下:
1. 处理数据,生成带排序规则的PPE因子
先提取每个Farmtype+PPE组合下Choice="Yes"对应的value,再按Farmtype分组,根据该value对PPE排序,最后将PPE重新编码为因子:
library(dplyr) library(ggplot2) df_sorted <- df %>% # 为每个Farmtype-PPE组合填充Yes对应的value值 group_by(Farmtype, PPE) %>% mutate(yes_value = ifelse(Choice == "Yes", value, NA)) %>% fill(yes_value, .direction = "updown") %>% ungroup() %>% # 按Farmtype分组,根据yes_value升序排序PPE(降序改order(desc(yes_value))) group_by(Farmtype) %>% mutate(PPE_sorted = factor(PPE, levels = unique(PPE[order(yes_value)]))) %>% ungroup()
2. 修改ggplot代码使用排序后的因子
将x轴映射改为处理后的PPE_sorted,同时添加scales="free_x"确保每个面板只显示自身的PPE类别:
ggplot(df_sorted, aes(x = PPE_sorted, y = value, fill = Choice)) + geom_bar(stat = "identity", position = "stack") + facet_grid(Farmtype ~ ., switch = "x", scales = "free_x") + labs(x = "个人防护装备(PPE)", y = "数值", fill = "选择") + ggtitle("按Choice='Yes'值排序的分组堆叠图") + theme_classic() + coord_flip()
关键说明
- 若要降序排序,只需把代码中的
order(yes_value)改成order(desc(yes_value))即可。 scales="free_x"参数可以避免每个面板出现不属于自身的PPE空条,让图表更整洁。fill(yes_value, .direction = "updown")确保同一Farmtype+PPE组合的所有行都能获取到Yes对应的value值,保证排序逻辑统一。
排序后,每个Farmtype面板内的PPE条会严格按照Choice="Yes"的value值顺序排列,比如Farm1面板中,Boots的Yes值为5会排在最上方(翻转后),Masks的Yes值为12排在最下方。
内容的提问来源于stack exchange,提问作者Mick
相关产品推荐
相关产品推荐

