R ggplot绘制年份分组双系列柱状图的数据整理方法
原始参考数据
| year | implicit | explicit |
|---|---|---|
| 2021 | 10 | 37 |
| 2020 | 13 | 19 |
| 2019 | 10 | 43 |
| 2018 | 15 | 28 |
| 2017 | 4 | 21 |
R ggplot2 分组柱状图实现方案
核心原理
ggplot2 所有分组类几何图形(分组柱、分组线等)都要求输入长格式数据:每一行对应一个独立观测(即「年份+指标类型」的组合),当前宽表将两个指标分别存在不同列,无法直接映射分组规则,需要先做格式转换,再调用绘图函数。
实现步骤
- 第一步:载入依赖包、读入原始数据
# 若未安装依赖,先运行 install.packages(c("ggplot2","tidyr")) library(ggplot2) library(tidyr) # 对应提供的原始宽表结构 df_wide <- data.frame( year = c(2021, 2020, 2019, 2018, 2017), implicit = c(10, 13, 10, 15, 4), explicit = c(37, 19, 43, 28, 21) )
- 第二步:宽表转长表
使用tidyr::pivot_longer()将分散的指标列合并为两列:一列存储指标类型(implicit/explicit),一列存储对应数值。
df_long <- df_wide |> pivot_longer( cols = c(implicit, explicit), # 指定需要合并的指标列 names_to = "metric", # 新列:存储指标名称 values_to = "val" # 新列:存储指标对应的数值 )
转换后的数据结构示例:
| year | metric | val |
|---|---|---|
| 2021 | implicit | 10 |
| 2021 | explicit | 37 |
| 2020 | implicit | 13 |
| 2020 | explicit | 19 |
- 第三步:绘制分组柱状图
使用geom_col()绘制柱状图(该函数直接读取给定数值,无需像geom_bar()一样做计数统计),通过position = position_dodge()设置柱子并排排列,避免堆叠。
ggplot(df_long, aes(x = factor(year), y = val, fill = metric)) + # 绘制分组柱,调整宽度避免柱子过宽/错位 geom_col(width = 0.7, position = position_dodge(width = 0.8)) + # 可选:在柱子顶部添加数值标签 geom_text( aes(label = val), position = position_dodge(width = 0.8), vjust = -0.3, # 标签偏移到柱子上方 size = 3.5 ) + # 自定义坐标轴与图例名称 labs( x = "年份", y = "统计值", fill = "指标类型" ) + # 按需调整X轴年份顺序,示例为从早到晚排序 scale_x_discrete(limits = as.character(2017:2021)) + # 套用简洁黑白主题 theme_bw()
常见踩坑说明
- 不要直接对宽表数据调用
geom_col()分别映射implicit和explicit列,这种写法无法自动生成正确的分组位置与图例 - 年份列必须转为因子类型,否则ggplot会将其识别为连续数值,X轴会出现不存在的小数年份刻度
position_dodge()的宽度参数需要和geom_col()的宽度参数匹配,否则会出现柱子与标签错位的问题
内容的提问来源于stack exchange,提问作者A_N_Wilson
相关产品推荐
相关产品推荐

