如何用ggplot的facet_wrap批量绘制分年份性别的Q1-Q5均值条形图?
优雅实现按年份、性别分组的Q1-Q5均值条形图(类密度效果)
需求说明
需要绘制按年份和性别分组的条形图,展示Q1至Q5变量的均值,呈现类似密度的视觉效果。
现有数据
data <- data.frame(userid = c(1,1,1,2,2,2,3,3,3), year = c(2013,2014,2015,2013,2014,2015,2013,2014,2015), gender = c(1,1,1,0,0,0,0,0,0), Q1 = c(3,2,3,1,0,1,2,1,0), Q2 = c(4,3,4,2,0,2,1,4,3), Q3 = c(1,2,1,3,5,4,5,4,5), Q4 = c(1,2,1,2,4,3,2,2,1), Q5 = c(1,1,1,2,1,0,0,0,1))
原有方法的局限
原有方法需要对年份和性别的每个组合重复执行筛选、汇总、绘图操作,代码冗余且效率低:
data %>% filter(gender==1,year==2013) %>% select(-userid,-gender,-year) %>% summarise_all(mean) %>% as.numeric() %>% barplot()
改进方案:用ggplot2 + facet_wrap批量实现
通过数据重塑+分面绘图,一次性生成所有分组的条形图,步骤如下:
1. 数据预处理(宽转长+分组计算均值)
先将宽格式数据转为长格式,再按year、gender、question(Q1-Q5)分组计算均值:
library(tidyverse) # 数据整理:宽转长 + 计算分组均值 summary_data <- data %>% select(-userid) %>% # 移除不需要的userid列 pivot_longer(cols = starts_with("Q"), names_to = "question", values_to = "score") %>% # 宽转长 group_by(year, gender, question) %>% # 按年份、性别、问题分组 summarise(mean_score = mean(score), .groups = "drop") # 计算均值并取消分组
2. 绘制分面条形图(类密度效果)
用ggplot2绘制条形图,通过facet_wrap按年份和性别组合分面,调整条形颜色和透明度实现类密度效果:
ggplot(summary_data, aes(x = question, y = mean_score, fill = question)) + geom_bar(stat = "identity", alpha = 0.7, width = 0.8) + # 绘制条形图,alpha调整透明度实现类密度感 facet_wrap(~ year + gender, labeller = labeller(gender = c("0" = "女性", "1" = "男性"))) + # 按年份+性别分面,自定义性别标签 labs(title = "各年份、性别分组下Q1-Q5均值", x = "问题", y = "均值分数") + theme_minimal() + theme(legend.position = "none") # 移除图例(x轴已标注问题)
效果说明
- 每个子图对应一个
年份+性别的组合,自动生成所有分组的图表 - 通过
alpha参数调整条形透明度,呈现类似密度的视觉效果 - 代码只需执行一次,无需重复编写筛选逻辑
内容的提问来源于stack exchange,提问作者HauptDa
相关产品推荐
相关产品推荐

