如何在R的ggplot分面网格各子图添加数据专属文本?
解决ggplot分面添加对应子集最值文本的问题
问题根源
你的代码里直接通过hrt_grps_smry$max_d[1]硬编码取第一个子集的最值,没有让ggplot根据sex/slp/exng这三个分面变量自动匹配对应子集的统计数据;同时手动计算的y轴位置基于全数据集的密度中位数,无法适配每个分面的直方图高度。
修复步骤
1. 重构统计汇总代码(替代原for循环)
用dplyr的分组汇总更简洁高效,同时保证分面变量的类型与主数据一致:
library(dplyr) library(ggplot2) # 加载数据 heart <- read.csv(file = 'C:/FilePath/heart.csv') # 按三个因子分组计算统计量,同时统一slp的因子顺序 hrt_grps_smry <- heart %>% group_by(sex, slp, exng) %>% summarize( max_d = max(age), min_d = min(age), mean_d = mean(age), `t.p-val` = t.test(age)$p.value, t.conf.L = t.test(age)$conf.int[[1]], t.conf.U = t.test(age)$conf.int[[2]], .groups = "drop" ) %>% mutate(across(slp, factor, levels = c(2, 0, 1))) # 和主数据保持相同的因子顺序
2. 修改分面绘图代码,自动匹配子集数据
利用Inf定位子图右上角,同时让ggplot通过分面变量自动匹配对应子集的最值:
heart %>% mutate(across(slp, factor, levels = c(2, 0, 1))) %>% ggplot(aes(x = age)) + geom_histogram(bins = 35) + facet_grid(sex ~ slp ~ exng) + # 添加最大值文本,自动匹配对应分面 geom_text( data = hrt_grps_smry, aes(x = Inf, y = Inf, label = paste("Max:", max_d)), hjust = 1.1, vjust = 1.2, size = 4, colour = "gray10" ) + # 添加最小值文本,自动匹配对应分面 geom_text( data = hrt_grps_smry, aes(x = Inf, y = Inf, label = paste("Min:", min_d)), hjust = 1.1, vjust = 2.4, size = 4, colour = "gray10" ) + ylab("Count")
关键说明
- 统计汇总表
hrt_grps_smry包含sex/slp/exng三个分面变量,ggplot会自动将每个分面与对应行的统计数据匹配,无需手动索引。 - 使用
x = Inf和y = Inf可以自动定位到每个子图的右上角,hjust和vjust用于微调文本位置,避免超出绘图区域。 - 统一主数据和汇总数据中
slp的因子顺序,确保分面的显示顺序与预期一致。
内容的提问来源于stack exchange,提问作者November2Juliet
相关产品推荐
相关产品推荐

