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

如何绘制按组划分、占比总和为100%的堆叠条形图?

堆叠条形图实现方案:对比IPN/INV组中各标志物的亚型占比分布

需求概述

  • 绘制堆叠条形图,展示IPN、INV两个组别中,各生物标志物(Marker)的4种亚型(WT、MUT-i、MUT-p、MUT-d)的分布差异
  • 要求每个标志物+组别组合下,4种亚型的占比总和为100%

原始数据

df <- structure(list(Marker = c("p16", "p16", "p16", "p16", "p16", 
"p16", "p16", "p16", "p53", "p53", "p53", "p53", "p53", "p53", 
"p53", "p53", "c-MET", "c-MET", "c-MET", "c-MET", "c-MET", "c-MET", 
"c-MET", "c-MET", "c-MYC", "c-MYC", "c-MYC", "c-MYC", "c-MYC", 
"c-MYC", "c-MYC", "c-MYC", "EGFR", "EGFR", "EGFR", "EGFR", "EGFR", 
"EGFR", "EGFR", "EGFR", "HER2-CISH", "HER2-CISH", "HER2-CISH", 
"HER2-CISH", "HER2-CISH", "HER2-CISH", "HER2-CISH", "HER2-CISH", 
"PD-L1 IC1%", "PD-L1 IC1%", "PD-L1 IC1%", "PD-L1 IC1%", "PD-L1 IC1%", 
"PD-L1 IC1%", "PD-L1 IC1%", "PD-L1 IC1%", "PD-L1 TPS1%", "PD-L1 TPS1%", 
"PD-L1 TPS1%", "PD-L1 TPS1%", "PD-L1 TPS1%", "PD-L1 TPS1%", "PD-L1 TPS1%", 
"PD-L1 TPS1%", "PD-L1 CPS1%", "PD-L1 CPS1%", "PD-L1 CPS1%", "PD-L1 CPS1%", 
"PD-L1 CPS1%", "PD-L1 CPS1%", "PD-L1 CPS1%", "PD-L1 CPS1%"), 
    Group = c("IPN", "IPN", "IPN", "IPN", "INV", "INV", "INV", 
    "INV", "IPN", "IPN", "IPN", "IPN", "INV", "INV", "INV", "INV", 
    "IPN", "IPN", "IPN", "IPN", "INV", "INV", "INV", "INV", "IPN", 
    "IPN", "IPN", "IPN", "INV", "INV", "INV", "INV", "IPN", "IPN", 
    "IPN", "IPN", "INV", "INV", "INV", "INV", "IPN", "IPN", "IPN", 
    "IPN", "INV", "INV", "INV", "INV", "IPN", "IPN", "IPN", "IPN", 
    "INV", "INV", "INV", "INV", "IPN", "IPN", "IPN", "IPN", "INV", 
    "INV", "INV", "INV", "IPN", "IPN", "IPN", "IPN", "INV", "INV", 
    "INV", "INV"), Subgroup = c("WT", "MUT-i", "MUT-p", "MUT-d", 
    "WT", "MUT-i", "MUT-p", "MUT-d", "WT", "MUT-i", "MUT-p", 
    "MUT-d", "WT", "MUT-i", "MUT-p", "MUT-d", "WT", "MUT-i", 
    "MUT-p", "MUT-d", "WT", "MUT-i", "MUT-p", "MUT-d", "WT", 
    "MUT-i", "MUT-p", "MUT-d", "WT", "MUT-i", "MUT-p", "MUT-d", 
    "WT", "MUT-i", "MUT-p", "MUT-d", "WT", "MUT-i", "MUT-p", 
    "MUT-d", "WT", "MUT-i", "MUT-p", "MUT-d", "WT", "MUT-i", 
    "MUT-p", "MUT-d", "WT", "MUT-i", "MUT-p", "MUT-d", "WT", 
    "MUT-i", "MUT-p", "MUT-d", "WT", "MUT-i", "MUT-p", "MUT-d", 
    "WT", "MUT-i", "MUT-p", "MUT-d", "WT", "MUT-i", "MUT-p", 
    "MUT-d", "WT", "MUT-i", "MUT-p", "MUT-d"), `Number of Cases` = c(59, 
    0, 1, 5, 42, 0, 0, 1, 42, 2, 3, 18, 27, 1, 2, 12, 7, 15, 
    11, 23, 14, 9, 10, 12, 56, 0, 1, 8, 41, 1, 0, 3, 17, 16, 
    11, 20, 18, 12, 10, 6, 60, 0, 0, 4, 44, 0, 0, 2, 60, 1, 1, 
    4, 42, 0, 0, 0, 63, 0, 0, 2, 39, 1, 0, 2, 48, 4, 4, 9, 31, 
    3, 1, 7)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-72L))

实现步骤

1. 数据预处理:计算占比

按Marker和Group分组,计算每个组合的总病例数,再推导各亚型的占比:

library(tidyverse)

df_percent <- df %>%
  group_by(Marker, Group) %>%
  mutate(
    Total = sum(`Number of Cases`),
    Percent = (`Number of Cases` / Total) * 100
  ) %>%
  ungroup()

2. 绘制堆叠条形图

使用ggplot2绘制分面堆叠条形图,直观对比两个组别中各标志物的亚型分布:

ggplot(df_percent, aes(x = Marker, y = Percent, fill = Subgroup)) +
  # 绘制堆叠条形
  geom_col(position = position_stack(), width = 0.7) +
  # 按Group分面,并排展示两个组别
  facet_wrap(~Group, ncol = 2) +
  # 添加占比标签(仅显示占比>2%的标签,避免重叠)
  geom_text(
    aes(label = ifelse(Percent > 2, sprintf("%.1f%%", Percent), "")),
    position = position_stack(vjust = 0.5),
    size = 3
  ) +
  # 选择区分度高的配色方案
  scale_fill_brewer(palette = "Set2") +
  # 设置坐标轴和图例标题
  labs(
    x = "生物标志物",
    y = "占比 (%)",
    fill = "亚型"
  ) +
  # 使用简洁主题,优化x轴标签显示
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    panel.spacing = unit(1, "lines")
  )

方案优势

  • 分组对比清晰:通过分面将IPN和INV组分开展示,便于直接对比同一标志物在两组中的亚型分布差异
  • 占比标准化:每个标志物+组别组合的亚型占比总和为100%,消除了组间样本量差异的干扰
  • 可读性强:添加占比标签并过滤小占比标签,避免视觉混乱;配色方案区分度高,便于识别不同亚型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:40:17