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

柱状图所有柱子高度错误一致,求R语言ggplot2代码问题排查

问题排查:ggplot2分组柱状图柱子高度一致的问题

问题描述

想用R语言ggplot2绘制分组柱状图,对比Young、Old两个年龄组在implvdm数值变量上的性别差异,但生成的图表中所有柱子高度错误一致,且不需要堆叠柱状图。

用户提供的代码

# Add a new column to indicate age group
young$age_group <- "Young"
old$age_group <- "Old"

# Combine the data frames
combined_df <- bind_rows(young, old)

# Plot
ggplot(combined_df, aes(x = age_group, y = implvdm, fill = gndr)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(x = "Age Group", y = "implvdm", fill = "Gender") +
  theme_minimal()

用户提供的数据

young <- structure(list(gndr = c("woman", "man", "man", "man", "woman", 
"man", "man", "woman", "woman", "man"), yrbrn = c(2003L, 1999L, 
1998L, 1999L, 2002L, 1999L, 2001L, 2004L, 2004L, 1999L), agea = c(18L, 
22L, 23L, 22L, 19L, 22L, 21L, 17L, 18L, 22L), impdema = c(6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L), implvdm = c(10L, 7L, 9L, 
7L, 10L, 10L, 9L, 10L, 8L, 10L), accalaw = c(0L, 2L, 1L, 0L, 
5L, 3L, 3L, 0L, 2L, 0L), imwbcnt = c(9L, 2L, 7L, 4L, 0L, 10L, 
2L, 3L, 7L, 6L), euftf = c(4L, 3L, 7L, 4L, 6L, 5L, 8L, 5L, 5L, 
9L), freehms = c(1L, 3L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 2L), gincdif = c(2L, 
3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L), prtclffi = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_)), row.names = c(NA, 
-10L), class = "data.frame")

old <- structure(list(gndr = c("man", "woman", "woman", "man", "woman", 
"man", "woman", "woman", "woman", "woman"), yrbrn = c(1943L, 
1975L, 1974L, 1977L, 1959L, 1993L, 1990L, 1993L, 1958L, 1971L
), agea = c(78L, 46L, 47L, 44L, 63L, 27L, 31L, 29L, 63L, 50L), 
    impdema = c(6L, 6L, 6L, 5L, 6L, 6L, 6L, 3L, 6L, 1L), implvdm = c(10L, 
    9L, 9L, 6L, 8L, 10L, 4L, 8L, 9L, 10L), accalaw = c(0L, 8L, 
    2L, 2L, 2L, 0L, 3L, 3L, 9L, 0L), imwbcnt = c(9L, 1L, 3L, 
    3L, 5L, 5L, 7L, 4L, 3L, 7L), euftf = c(8L, 2L, 4L, 3L, 4L, 
    3L, 7L, 5L, 4L, 5L), freehms = c(2L, 2L, 4L, 2L, 2L, 1L, 
    4L, 2L, 4L, 1L), gincdif = c(2L, 2L, 2L, 3L, 2L, 4L, 1L, 
    2L, 2L, 3L), prtclffi = c(NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_, NA_integer_)), row.names = c(NA, -10L), class = "data.frame")

问题原因

使用geom_bar(stat = "identity")时,ggplot会将每组(年龄组+性别)下所有行的implvdm值直接求和作为柱子高度。巧合的是你提供的数据中,四个分组(Young-woman、Young-man、Old-woman、Old-man)的implvdm总和完全相同,所以柱子高度看起来一致。但你实际需要的应该是各组的均值(或其他统计量),而非总和。

解决方法

有两种常用实现方式:

方式1:提前汇总数据再绘图

先通过分组计算得到每组的统计量(比如均值),再基于汇总后的数据绘图:

library(dplyr)
library(ggplot2)

# 合并数据(保留原步骤)
young$age_group <- "Young"
old$age_group <- "Old"
combined_df <- bind_rows(young, old)

# 按年龄组和性别分组,计算implvdm的均值
summary_df <- combined_df %>%
  group_by(age_group, gndr) %>%
  summarise(mean_implvdm = mean(implvdm), .groups = "drop")

# 绘制分组柱状图
ggplot(summary_df, aes(x = age_group, y = mean_implvdm, fill = gndr)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(x = "年龄组", y = "implvdm均值", fill = "性别") +
  theme_minimal()

方式2:直接用stat_summary计算统计量

在绘图时通过stat_summary直接指定要计算的统计量,无需提前汇总:

library(ggplot2)
library(dplyr)

# 合并数据(保留原步骤)
young$age_group <- "Young"
old$age_group <- "Old"
combined_df <- bind_rows(young, old)

# 绘制分组柱状图,直接计算均值
ggplot(combined_df, aes(x = age_group, y = implvdm, fill = gndr)) +
  stat_summary(fun = mean, geom = "bar", position = "dodge") +
  labs(x = "年龄组", y = "implvdm均值", fill = "性别") +
  theme_minimal()

如果需要中位数、最大值等其他统计量,只需将fun = mean替换为fun = median、fun = max等即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 05:40:55