如何绘制按组划分、占比总和为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
相关产品推荐
相关产品推荐

