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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:17:40