如何用ggplot绘制含合并分组的百分比堆叠条形图?(R语言)
解决R语言堆叠条形图的百分比计算与绘图问题
以下是完整的数据处理与绘图代码,解决你遇到的条形总和超100%、Other组划分不符合占比的问题:
1. 加载所需包
library(dplyr) library(ggplot2)
2. 原始数据(你的数据)
df <- data.frame( groups = c(rep("A", 5), rep("B", 3), rep("C", 2), rep(c("D","E","F","G","H"), 1)), subgroups = paste0("Subgroup", 1:15), length = c(103,112,141,152,50, 77,82,88, 59,86, 3,17,1,5,24))
3. 数据预处理
核心是明确两个百分比层级:子组长度占总长度的百分比(用于堆叠后得到组的总占比)、子组长度在所属组内的百分比(用于标签显示),同时合并E/F/G/H为Other组:
# 计算所有长度的总和 total_length <- sum(df$length) df_processed <- df %>% # 合并指定组为Other mutate(groups = ifelse(groups %in% c("E", "F", "G", "H"), "Other", groups)) %>% # 按主组分组计算组内总长度 group_by(groups) %>% mutate( group_total = sum(length), # 子组长度占总长度的百分比:堆叠后自动累加为该主组的总占比 sub_pct_total = (length / total_length) * 100, # 子组长度在所属组内的百分比:用于显示内部占比标签 sub_pct_group = round((length / group_total) * 100, 1) ) %>% ungroup()
4. 绘制堆叠条形图
直接用子组占总长度的百分比作为y值,堆叠后每个条形的高度就是主组的总占比,内部按子组实际长度占比划分:
ggplot(df_processed, aes(x = groups, y = sub_pct_total, fill = subgroups)) + # 绘制堆叠条形(stat="identity"直接使用y值) geom_bar(stat = "identity", width = 0.7) + # 添加主组总占比的顶部标签 geom_text( aes(label = paste0(round(group_total / total_length * 100, 1), "%")), stat = "summary", fun = sum, vjust = -0.3, size = 3.5 ) + # 添加子组在组内的占比标签(居中显示) geom_text( aes(label = paste0(sub_pct_group, "%")), position = position_stack(vjust = 0.5), size = 2.8 ) + # 自定义标签与主题 labs( x = "主组", y = "占总长度的百分比 (%)", fill = "子组" ) + theme_minimal() + theme(legend.position = "right")
问题原因说明
你之前遇到的问题大概率是以下两种情况:
- 错误使用了
position = "fill":该参数会强制每个条形高度拉伸至100%,而非保留主组的实际总占比; - 百分比计算层级混淆:直接用子组在组内的占比作为y值,导致每个条形堆叠后总和为100%,而非主组占总长度的百分比。
内容的提问来源于stack exchange,提问作者cookiemonster
相关产品推荐
相关产品推荐

