柱状图所有柱子高度错误一致,求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
相关产品推荐
相关产品推荐

