R语言:带双重分组与三类数据的堆叠条形图制作求助
别担心,这个需求确实需要一点数据整理和ggplot的技巧,但一步步拆解下来其实并不难!我会用新手友好的tidyverse工具链(dplyr+ggplot2)帮你实现,从数据预处理到绘图全程讲解~
第一步:加载必要的工具包
首先安装并加载tidyverse(包含dplyr用于数据整理,ggplot2用于绘图),如果之前没装过就先运行安装命令:
# 首次使用先安装 # install.packages("tidyverse") library(tidyverse)
第二步:加载你的样本数据
直接用你提供的代码加载数据就行:
data1 <- read.table (text= "Plant RIL Trt SW_Before SW_After SW_Total 1 85 206 Early 0.380 2.27 2.65 2 88 166 Early 0 0.311 0.311 3 92 Lindo Early 0 0.663 0.633 4 94 158 Early 0.0738 0.596 0.669 5 95 23 Early 0.0252 0.543 0.795 6 97 Lica Early 0 0.646 0.646 7 104 166 Peak 0.227 0.261 0.488 8 108 Lica Peak 0.0705 0.816 0.887 9 113 Lindo Late 0.628 0 0.628 10 115 206 Late 0.544 1.05 1.60 11 115 206 Control NA NA 1.50", sep="", header=T)
第三步:数据整理(核心步骤!)
因为Control组和其他处理组的数据结构不一样(只有Total列),我们需要分开处理再合并:
- 处理非Control组:计算均值并转成绘图友好的格式
非Control组需要按RIL和Trt分组,自动计算SW_Before和SW_After的均值(比如RIL206的多行数据会自动取平均),然后把宽格式数据转成长格式,方便后续堆叠绘图:
non_control_data <- data1 %>% filter(Trt != "Control") %>% # 筛选出非Control的行 group_by(RIL, Trt) %>% # 按RIL+处理组分组计算均值 summarise( SW_Before = mean(SW_Before, na.rm = TRUE), SW_After = mean(SW_After, na.rm = TRUE), .groups = "drop" # 取消分组,避免后续报错 ) %>% pivot_longer( cols = c(SW_Before, SW_After), # 把Before/After列转成键值对 names_to = "Measurement", # 新列:标记是Before还是After values_to = "Mean_Value" # 新列:存储计算好的均值 )
- 处理Control组:适配格式方便合并
Control组只有SW_Total数据,我们把它转换成和非Control组一致的格式:
control_data <- data1 %>% filter(Trt == "Control") %>% # 筛选Control组 select(RIL, Trt, SW_Total) %>% # 保留需要的列 rename(Mean_Value = SW_Total) %>% # 把列名改成和非Control组一致 mutate(Measurement = "SW_Total") # 添加测量类型标记
- 合并两组数据
把处理好的两部分数据合并成最终绘图用的数据框:
plot_data <- bind_rows(non_control_data, control_data)
第四步:绘制符合需求的堆叠条形图
现在用ggplot绘制完全符合你要求的图表:
- X轴按
RIL分组,同一个RIL下的不同Trt条形分开显示 - 堆叠部分展示
SW_Before/SW_After(Control组显示SW_Total) - 每个条形标注
Trt名称,用颜色区分不同测量类型
ggplot(plot_data, aes(x = RIL, y = Mean_Value, fill = Measurement)) + # 绘制堆叠条形,同时按Trt分组(同一个RIL下的Trt条形分开) geom_col(position = position_dodge(width = 0.8), color = "black") + # 给每个条形添加Trt标注,放在条形上方避免重叠 geom_text( aes(label = Trt), position = position_dodge(width = 0.8), vjust = -0.5, size = 3.5 ) + # 自定义颜色,让Control的Total和其他测量类型区分开 scale_fill_manual( values = c( "SW_Before" = "#619CFF", "SW_After" = "#00BA38", "SW_Total" = "#B7B7B7" ), labels = c("SW Before", "SW After", "SW Total (Control)") ) + # 添加标题和坐标轴标签 labs( title = "Mean SW Values by RIL and Treatment", x = "RIL", y = "Mean Value", fill = "Measurement Type" ) + # 调整主题,让图表更清晰易读 theme_bw() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.text.x = element_text(angle = 45, hjust = 1), legend.position = "bottom" )
关键细节说明
position_dodge(width = 0.8):让同一个RIL下的不同Trt条形分开,避免重叠group_by()+summarise():自动处理RIL206这类多行数据,计算均值- 颜色区分:用不同色调标记Before/After/Total,Control组的灰色一眼就能识别
内容的提问来源于stack exchange,提问作者Cameron So
相关产品推荐
相关产品推荐

