如何让ggplot分组柱状图中每组内的柱子按平均任期降序排列?
分组柱状图内按数值降序排列柱子的解决方案
问题背景
我需要创建分组柱状图,展示国防、农业、财政、外交四类内阁部长在政党制、个人制、军事制、君主制四类独裁政体中的平均任期。现有代码生成的图表中,每个政体分组内的柱子顺序固定,需求是让每个分组内的柱子按平均任期降序排列(任期最长的部长柱子排在最前)。
数据集
structure(list(minister_type = c("Defense", "Finance", "Foreign Affairs", "Agriculture", "Defense", "Finance", "Foreign Affairs", "Agriculture", "Defense", "Foreign Affairs", "Finance", "Agriculture", "Defense", "Foreign Affairs", "Finance", "Agriculture"), regime_subtype = c("Military", "Military", "Military", "Military", "Monarch", "Monarch", "Monarch", "Monarch", "Party", "Party", "Party", "Party", "Personal", "Personal", "Personal", "Personal"), average_tenure = c(2.60493827160494, 2.48979591836735, 2.33165829145729, 2.19170984455959, 5.94202898550725, 4.20212765957447, 4.14772727272727, 3.35576923076923, 4.93292682926829, 4.60164835164835, 3.91704035874439, 3.49769585253456, 3.46043165467626, 2.99093655589124, 2.78651685393258, 2.57228915662651)), row.names = c(NA, -16L), class = "data.frame")
原代码
# Create the grouped bar plot ggplot(sorted_df, aes(x = regime_subtype, y = average_tenure, fill = minister_type)) + geom_bar(stat = "identity", position = "dodge") + scale_fill_manual(values = minister_colors) + labs(x = "Regime Subtype", y = "Average Tenure", fill = "Minister Type") + ggtitle("Average Tenure by Minister Type and Regime Subtype") + theme_minimal()
解决方案
核心是为每个政体分组生成按任期降序排列的部长类型因子,让ggplot按因子水平顺序绘制柱子。
1. 数据预处理(生成排序后的因子)
使用dplyr分组排序,创建带顺序的因子列:
library(dplyr) library(ggplot2) # 加载数据(替换为你的数据框) df <- structure(...) # 这里放入上述数据集代码 # 分组排序并生成有序因子 sorted_df <- df %>% group_by(regime_subtype) %>% arrange(desc(average_tenure), .by_group = TRUE) %>% mutate(minister_ordered = factor(minister_type, levels = unique(minister_type))) %>% ungroup()
2. 修改绘图代码
替换填充变量为有序因子,调整柱子对齐:
# 定义颜色映射(可根据需求修改) minister_colors <- c("Defense" = "#1f77b4", "Finance" = "#ff7f0e", "Foreign Affairs" = "#2ca02c", "Agriculture" = "#d62728") # 绘制排序后的分组柱状图 ggplot(sorted_df, aes(x = regime_subtype, y = average_tenure, fill = minister_ordered)) + geom_bar(stat = "identity", position = position_dodge(width = 0.9)) + scale_fill_manual(values = minister_colors, name = "Minister Type") + labs(x = "Regime Subtype", y = "Average Tenure") + ggtitle("Average Tenure by Minister Type and Regime Subtype") + theme_minimal()
关键说明
group_by()+arrange(.by_group = TRUE):确保每个政体分组内按任期降序排列mutate(factor(...)):将每个分组内的部长类型按排序后的顺序设置为因子水平,ggplot会遵循此顺序绘制柱子position_dodge(width = 0.9):手动指定柱子间距,避免分组内柱子错位
内容的提问来源于stack exchange,提问作者w5698
相关产品推荐
相关产品推荐

