如何在R中绘制按性别分组的年份堆叠条形图
解决堆叠条形图绘制问题
你的问题核心在于当前数据是宽格式,而ggplot2更适合处理长格式数据,同时你需要明确区分性别和年龄组的分组逻辑。下面是一步步的解决方案:
1. 加载所需包
首先确保你安装并加载了tidyverse(包含数据整理的dplyr和绘图的ggplot2):
library(tidyverse)
2. 整理数据(宽转长,拆分性别与年龄组)
你的原始数据中,每个列名包含了性别和年龄组信息,我们需要先移除总计列(避免堆叠重复),然后将数据转换为长格式,并拆分出性别和年龄组:
# 先复制你的样本数据(方便测试) Refugees_demographics <- structure(list(Year = c(2006, 2007), `Female 0-4` = c(0, 3), `Female 5-11` = c(0, 0), `Female 12-17` = c(140, 36), `Female 18-59` = c(1118, 519), `Female 60+` = c(121, 85), `F: Total` = c(1379, 643 ), `Male 0-4` = c(0, 7), `Male 5-11` = c(6, 1), `Male 12-17` = c(152, 56), `Male 18-59` = c(1323, 870), `Male 60+` = c(595, 88), `M: Total` = c(2076, 1022)), row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame")) # 数据整理 tidy_data <- Refugees_demographics %>% # 移除总计列 select(-contains("Total")) %>% # 宽转长:将所有年龄组列转为行 pivot_longer(cols = -Year, names_to = "Gender_Age", values_to = "Count") %>% # 拆分性别和年龄组 separate(Gender_Age, into = c("Gender", "Age_Group"), sep = " ", extra = "merge") %>% # 统一性别名称(让标签更友好) mutate(Gender = case_when( Gender == "Female" ~ "Female", Gender == "Male" ~ "Male" ))
3. 绘制目标堆叠条形图
现在我们可以绘制每年包含男女两个堆叠条、每个条内按年龄组堆叠的图形:
ggplot(tidy_data, aes(x = factor(Year), y = Count, fill = Age_Group)) + # 堆叠条形图,同时按性别分组并排显示 geom_col(aes(group = Gender), position = position_dodge(width = 0.8), width = 0.7) + # 添加数值标签(可选,让数据更清晰) geom_text(aes(label = Count), position = position_stack(vjust = 0.5), size = 3, color = "white") + # 设置坐标轴和标题 labs( x = "Year", y = "Number of Refugees", fill = "Age Group", title = "Refugee Demographics by Year, Gender and Age Group" ) + # 调整主题样式(可选) theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
关键逻辑解释
pivot_longer:把宽格式数据转为长格式,让每个年龄组的数值成为单独的行,这是ggplot2处理分组数据的核心前提。separate:从列名中拆分出性别和年龄组,让我们能分别控制“男女并排”和“年龄组堆叠”两个维度。position_dodge(width = 0.8):让同一年份的男女堆叠条并排显示,避免重叠;group = Gender确保ggplot识别到性别分组逻辑。position_stack(vjust = 0.5):让数值标签自动显示在每个堆叠块的中间位置,提升可读性。
这样就能得到你想要的:X轴为年份,每年两个堆叠条(男女),每个条内按年龄组堆叠的条形图。
内容的提问来源于stack exchange,提问作者sodasky
相关产品推荐
相关产品推荐

