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

如何在ggplot的facet_wrap中添加年份×处理多分组的均值?

问题描述

使用ggplot2的facet_wrap按品种分面绘制图表时,希望为每个分面内的2个年份×2种处理共4个交叉分组添加均值文本或竖线。此前尝试group_by仅能实现单分组(年份或处理)的均值计算,询问是否可以实现年份与处理双分组的均值添加。

原始数据

structure(list(Year = c(2021, 2021, 2021, 2021, 2021, 2021, 2021, 
2021, 2021, 2021, 2021, 2021, 2017, 2017, 2017, 2017, 2017, 2017, 
2017, 2017, 2017, 2017, 2017, 2017), Pos_heliaphen = c("W13", 
"W44", "X23", "Y42", "Z07", "Z36", "W45", "X22", "X30", "Y43", 
"Z06", "Z37", "Y36", "Z06", "Z18", "Z24", "Z40", "Z43", "Y35", 
"Z05", "Z17", "Z23", "Z39", "Z44"), Treatment = c("Non-irrigated", 
"Non-irrigated", "Non-irrigated", "Non-irrigated", "Non-irrigated", 
"Non-irrigated", "Irrigated", "Irrigated", "Irrigated", "Irrigated", 
"Irrigated", "Irrigated", "Non-irrigated", "Non-irrigated", "Non-irrigated", 
"Non-irrigated", "Non-irrigated", "Non-irrigated", "Irrigated", 
"Irrigated", "Irrigated", "Irrigated", "Irrigated", "Irrigated"
), Variety = c("ES Pallador - MG I", "ES Pallador - MG I", "ES Pallador - MG I", 
"Sultana - MG 000", "Sultana - MG 000", "Sultana - MG 000", "ES Pallador - MG I", 
"ES Pallador - MG I", "ES Pallador - MG I", "Sultana - MG 000", 
"Sultana - MG 000", "Sultana - MG 000", "ES Pallador - MG I", 
"ES Pallador - MG I", "ES Pallador - MG I", "Sultana - MG 000", 
"Sultana - MG 000", "Sultana - MG 000", "ES Pallador - MG I", 
"ES Pallador - MG I", "ES Pallador - MG I", "Sultana - MG 000", 
"Sultana - MG 000", "Sultana - MG 000"), SLA = c(127.105797101449, 
135.263238679969, 135.57233201581, 120.477777777778, 149.139664804469, 
139.5776, 142.927987742594, 139.450256889304, 152.589150943396, 
102.962703962704, 114.160714285714, 106.182042833608, 29.168895183201, 
61.5906086966241, 14.65223598377, 73.8218290951699, 29.0006487652397, 
37.6144729444593, 103.550713082565, 118.558911914481, 116.11947891962, 
91.7471974108231, 78.2428634817335, 91.5116772823779)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -24L))

现有绘图代码

library(ggplot2)
library(dplyr)

df %>%
  mutate(across(Variety, factor, levels=c("Sultana - MG 000","ES Pallador - MG I","Isidor - MG I",
                                          "Santana - MG I/II","Blancas - MG II","Ecudor - MG II")))%>%
  ggplot(aes(y=Treatment,x=SLA,group=Year))+
  geom_point(aes(color = as.factor(Year),shape=Treatment),size=3,alpha = 0.7)+
  labs(x = expression(paste('SLA (cm'^2,'·','g'^-1,')')),
       y = "Treatment")+
  scale_color_manual(values = c("#FF6600","#336699"))+
  scale_shape_manual(values = c(16,1))+
  theme_bw() + 
  theme(axis.text.x = element_text(size=13,vjust=0.5),
        axis.text.y = element_text(size=13),
        axis.title.x = element_text(size = 14),
        axis.title.y = element_text(size = 14),
        legend.title=element_text(size=14),
        legend.text=element_text(size=12),
        legend.position = "bottom" )+
  guides(color = guide_legend(title = "Year"),shape = guide_legend(title = "Treatment"))+
  facet_wrap(~Variety)
解决方案

完全可以实现双分组的均值添加,核心是先通过group_by同时按**品种(Variety)、年份(Year)、处理(Treatment)**三个维度分组计算均值,再将计算结果传入ggplot中添加对应的图层。

步骤1:预处理计算交叉分组均值

# 计算每个品种-年份-处理组合的SLA均值
mean_df <- df %>%
  group_by(Variety, Year, Treatment) %>%
  summarise(mean_SLA = mean(SLA, na.rm = TRUE), .groups = "drop")

步骤2:更新绘图代码,添加均值竖线与文本

df %>%
  mutate(across(Variety, factor, levels=c("Sultana - MG 000","ES Pallador - MG I","Isidor - MG I",
                                          "Santana - MG I/II","Blancas - MG II","Ecudor - MG II"))) %>%
  ggplot(aes(y=Treatment,x=SLA,group=Year))+
  # 原始散点图层
  geom_point(aes(color = as.factor(Year),shape=Treatment),size=3,alpha = 0.7)+
  # 添加均值竖线:对应每个交叉分组的均值位置,颜色匹配年份
  geom_vline(data = mean_df, aes(xintercept = mean_SLA, color = as.factor(Year)), 
             linetype = "dashed", linewidth = 1)+
  # 添加均值文本:标注在竖线右侧,保留1位小数
  geom_text(data = mean_df, aes(x = mean_SLA, y = Treatment, label = round(mean_SLA, 1), 
                                color = as.factor(Year)), 
            hjust = -0.2, size = 4)+
  labs(x = expression(paste('SLA (cm'^2,'·','g'^-1,')')),
       y = "处理方式")+
  scale_color_manual(values = c("#FF6600","#336699"))+
  scale_shape_manual(values = c(16,1))+
  theme_bw() + 
  theme(axis.text.x = element_text(size=13,vjust=0.5),
        axis.text.y = element_text(size=13),
        axis.title.x = element_text(size = 14),
        axis.title.y = element_text(size = 14),
        legend.title=element_text(size=14),
        legend.text=element_text(size=12),
        legend.position = "bottom" )+
  guides(color = guide_legend(title = "年份"),shape = guide_legend(title = "处理方式"))+
  facet_wrap(~Variety)

代码说明

  • group_by(Variety, Year, Treatment):同时按三个维度分组,确保每个分面(品种)内的每个年份-处理交叉组都能计算出独立的均值
  • geom_vline:利用预处理的均值数据绘制垂直参考线,线型设为虚线便于区分原始数据点
  • geom_text:将均值数值标注在竖线右侧,hjust=-0.2避免文本与竖线重叠,round()简化数值显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:15:53