在R中绘制带堆叠子类别分组条形图并叠加数值折线图
R语言实现堆叠+分组条形图+折线图的解决方案
核心思路
要同时展示两个分类变量(一个堆叠、一个分组)的频率,再叠加折线图,关键是把两个分类变量的数据整理成统一的长格式,然后用ggplot2分层绘制不同类型的条形,再处理双y轴适配折线数据。
步骤1:数据整理
先把tromboprofil和tratamiento_mieloma的频率数据统一格式,合并到同一个数据框,同时保留折线图的line_data:
library(tidyverse) # 给两个分类变量添加类型标识,统一列名(替换成你的实际列名) trombo_formatted <- tromboprofil %>% mutate(var_type = "tromboprofil") %>% rename(sub_cat = 你的子类别列名, freq = 你的频率列名) trat_formatted <- tratamiento_mieloma %>% mutate(var_type = "tratamiento_mieloma") %>% rename(sub_cat = 你的子类别列名, freq = 你的频率列名) # 合并两个数据集 combined_freq <- bind_rows(trombo_formatted, trat_formatted) # 确保时期列是因子(避免x轴乱序) combined_freq$period <- factor(combined_freq$period, levels = unique(combined_freq$period)) line_data$period <- factor(line_data$period, levels = unique(line_data$period))
步骤2:绘图代码
用ggplot2分层绘制堆叠条形、分组条形和折线,同时适配双y轴:
library(ggplot2) # 初始化绘图 ggplot() + # 绘制堆叠条形:tromboprofil geom_bar( data = filter(combined_freq, var_type == "tromboprofil"), aes(x = period, y = freq, fill = sub_cat), stat = "identity", position = position_stack() ) + # 绘制分组条形:tratamiento_mieloma(用空心+边框区分堆叠条) geom_bar( data = filter(combined_freq, var_type == "tratamiento_mieloma"), aes(x = period, y = freq, color = sub_cat), stat = "identity", position = position_dodge(width = 0.8), # 分组间距 fill = NA, # 空心显示 size = 1 ) + # 绘制折线图:事件数量(转换数值适配左侧y轴) geom_line( data = line_data, aes( x = period, y = events / max(events) * max(combined_freq$freq), # 比例缩放 group = 1 ), color = "#000000", size = 1.2 ) + geom_point( data = line_data, aes( x = period, y = events / max(events) * max(combined_freq$freq) ), color = "#000000", size = 3 ) + # 设置双y轴 scale_y_continuous( name = "频率", sec.axis = sec_axis( ~ . * max(line_data$events) / max(combined_freq$freq), # 反向转换回事件数 name = "事件数量" ) ) + # 图例与主题调整 labs( fill = "Tromboprofil 子类别", color = "Tratamiento Mieloma 子类别" ) + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1))
关键细节说明
- 数据合并:通过
bind_rows把两个分类变量的数据合并,用var_type区分,解决你之前无法同时调用两个变量的问题。 - 条形区分:堆叠条形用填充色,分组条形用边框色+空心,避免视觉重叠;也可以给分组条形的x轴加小偏移(比如
x = as.numeric(period) + 0.2)来错开位置。 - 双y轴适配:折线的事件数需要按比例缩放到频率的数值范围,再通过
sec_axis反向转换,保证两个轴的刻度对应。
内容的提问来源于stack exchange,提问作者Sandra R
相关产品推荐
相关产品推荐

