ggplot堆叠百分比柱状图绘制异常问题求助
堆叠百分比柱状图绘制错误求助
我能正常绘制普通堆叠柱状图,但将position参数从"stacked"改为"fill"后,得到了错误的图表:

我使用的代码如下:
ggplot(dataset, aes(fill = family_role_recoded, x=country, y=family_role_recoded)) + geom_bar(position="fill", stat="identity")
以下是可复现示例数据集:
structure(list(country = c("Lebanon", "Algeria", "Iraq", "Jordan", "Morocco", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon", "Lebanon"), urban_rural = structure(c(2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 1L, 2L, 2L), levels = c("Rural", "Urban", "Refugee camp"), class = "factor"), age = c(41L, 36L, 33L, 26L, 28L, 33L, 31L, 45L, 70L, 18L, 23L, 20L, 24L, 44L, 38L, 39L, 23L, 45L, 26L, 54L, 26L, 22L, 33L, 62L, 18L), education = c("Preparatory/Basic", "Preparatory/Basic", "Secondary", "Elementary", "Mid-level diploma/professional or technical", "Secondary", "Elementary", "Elementary", "Elementary", "Secondary", "BA", "Secondary", "BA", "Preparatory/Basic", "Elementary", "BA", "Secondary", "BA", "Preparatory/Basic", "Secondary", "Secondary", "Preparatory/Basic", "Preparatory/Basic", "Preparatory/Basic", "Secondary"), family_role = structure(c(1L, 2L, 2L, 1L, 2L, 2L, 2L, 3L, 2L, 3L, 2L, 3L, 1L, 3L, 2L, 3L, 3L, 2L, 2L, 4L, 2L, 2L, 3L, 1L, 3L), levels = c("I strongly agree", "I agree", "I disagree", "I strongly disagree", "Don't know", "Refused to answer"), class = "factor"), religious = structure(c(2L, 1L, 2L, 2L, 3L, 2L, 2L, 3L, 1L, 3L, 3L, 1L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L), levels = c("Religious", "Somewhat religious", "Not religious" ), class = "factor"), gender = c("Male", "Female", "Female", "Male", "Male", "Male", "Male", "Male", "Male", "Male", "Female", "Male", "Male", "Female", "Male", "Female", "Female", "Male", "Female", "Female", "Male", "Male", "Male", "Female", "Male" ), education_cat = structure(c(2L, 2L, 3L, 2L, 3L, 3L, 2L, 2L, 2L, 3L, 4L, 3L, 4L, 2L, 2L, 4L, 3L, 4L, 2L, 3L, 3L, 2L, 2L, 2L, 3L), levels = c("No formal education", "Basic education", "Secondary education", "Higher education"), class = "factor"), family_role_recoded = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 1L), levels = c("Disagree/strongly disagree", "Agree/strongly agree", "Don't know"), class = "factor")), row.names = c(NA, 25L), class = "data.frame")
问题原因及解决方法
你的代码核心问题是将分类变量family_role_recoded映射给了y轴,同时使用stat="identity"。stat="identity"要求y轴是数值型数据,此时ggplot会把分类变量自动转换为底层的整数编码(比如1、2),导致计算出的比例完全错误,从而生成异常图表。
解法1:让ggplot自动统计计数(最简方式)
直接移除y参数和stat="identity"(geom_bar默认stat="count",会自动统计每个分组的数量),设置position="fill"即可生成百分比堆叠柱状图:
library(ggplot2) ggplot(dataset, aes(x = country, fill = family_role_recoded)) + geom_bar(position = "fill") + scale_y_continuous(labels = scales::percent) # 可选:将y轴标签改为百分比格式
解法2:手动预处理数据(更灵活可控)
如果需要更清晰地控制统计逻辑,可以先用dplyr统计各分组的占比,再绘图:
library(ggplot2) library(dplyr) # 先统计每个国家下各family_role的数量及占比 summary_data <- dataset %>% count(country, family_role_recoded) %>% group_by(country) %>% mutate(percent = n / sum(n)) # 绘制堆叠百分比柱状图 ggplot(summary_data, aes(x = country, y = percent, fill = family_role_recoded)) + geom_col() + # geom_col对应stat="identity",适合已统计好的数据 scale_y_continuous(labels = scales::percent)
两种方法都能生成正确的堆叠百分比柱状图,你可以根据需求选择。
内容的提问来源于stack exchange,提问作者Nicosc
相关产品推荐
相关产品推荐

