You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ggplot中基于两列数值生成dodged columns graph

双系列分栏柱形图(dodged columns)的两种实现路径

不使用pivot_longer()的实现方案

很多人初次尝试时会直接把两个value列写在aes映射里,其实fill参数只支持映射分类型数据列,不能直接把数值列当分组依据。完全可以在不调整原数据宽格式的前提下完成绘图,核心逻辑是利用ggplot多层几何对象的特性,分别为两个数值列单独绘制柱形,通过统一的横向偏移参数实现分栏对齐。

实现代码示例:

library(ggplot2)
# 载入演示数据集
demo_df <- data.frame(
  occ_status_before = c("在职(worked)", "自主就业(independent)", "失业(unemployed)"),
  value_before = c(0.3, 0.4, 0.2),
  value_after = c(0.35, 0.36, 0.9)
)

ggplot(demo_df, aes(x = occ_status_before)) +
  # 绘制第一组(统计时点前)的柱形
  geom_col(
    aes(y = value_before, fill = "统计时点前"),
    position = position_dodge(width = 0.9),
    width = 0.8
  ) +
  # 绘制第二组(统计时点后)的柱形,使用完全一致的dodge宽度保证对齐
  geom_col(
    aes(y = value_after, fill = "统计时点后"),
    position = position_dodge(width = 0.9),
    width = 0.8
  ) +
  # 匹配填充色对应的图例
  scale_fill_discrete(name = "指标维度") +
  labs(x = "就业状态", y = "数值占比")
  • 适用场景:临时快速出图、只有2个对比系列的简单场景,不需要改动原数据结构。
  • 注意点:两个geom_col层设置的position_dodge(width=)参数必须完全一致,否则会出现两个系列柱形横向错位的问题。
  • 局限:当对比系列超过2个时,需要逐次叠加geom_col层,反复手动调整偏移参数,很容易出现柱形错位、图例维护成本高的问题。

基于pivot_longer()的标准实现方案

这是ggplot2生态推荐的适配方式,通过把宽格式数据转为“分类维度-数值”的长结构,一次映射即可自动完成分栏、对齐、图例生成,适配任意数量的对比系列。
操作步骤:

  1. 用tidyr::pivot_longer()将多列宽格式数据转为长格式:
library(tidyr)
long_df <- demo_df %>% 
  pivot_longer(
    cols = starts_with("value_"), # 匹配所有需要转为长格式的数值列
    names_to = "time_period", # 存储原列分组名的新列
    values_to = "value", # 存储原列数值的新列
    names_prefix = "value_" # 自动去掉原列名的冗余前缀,得到更简洁的分组标签
  )

处理完成后的长格式数据会变为:每个就业状态下对应2行记录,分别匹配统计时点前、后的数值,刚好适配ggplot的分组映射逻辑。

  1. 基于长格式数据绘制分栏柱形图:
ggplot(long_df, aes(x = occ_status_before, y = value, fill = time_period)) +
  geom_col(position = position_dodge(width = 0.9), width = 0.8) +
  labs(x = "就业状态", y = "数值占比", fill = "统计时点")
  • 优势:代码简洁,不需要手动叠加多层几何对象;柱形对齐、图例生成全自动化,不存在错位风险;后续调整颜色、增加误差线、切换其他几何对象时,只需要调整映射关系即可,可维护性远高于手动叠层的方式。

内容的提问来源于stack exchange,提问作者iftach s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 18:45:03