如何用ggplot2绘制多箱线图展示emmeans成对比较结果
问题描述
我想用ggplot2在同一张图表中绘制多个箱线图,展示模型的成对比较结果。我的模型及使用emmeans进行的成对比较如下:
mod1 <- lmer(CONT_Y ~ MY_GROUP * YEAR + (1|ID), data = dfModels) group <- emmeans(mod1,~ MY_GROUP|YEAR) year <- emmeans(mod1,~YEAR|MY_GROUP) my_pairs <- data.frame(group_p) %>% full_join(data.frame(year_p))
成对比较结果:
| contrast | YEAR | MY_GROUP | estimate | SE | df | t.ratio | p.value |
|---|---|---|---|---|---|---|---|
| L1 - L2 | 2020 | -0.91 | 0.53 | 60 | -1.73 | 0.09 | |
| L1 - L2 | 2021 | -0.31 | 0.53 | 60 | -0.59 | 0.56 | |
| YEAR2020 - YEAR2021 | G1 | -1.14 | 0.53 | 60 | -2.16 | 0.03 | |
| YEAR2020 - YEAR2021 | G2 | -0.54 | 0.53 | 60 | -1.02 | 0.31 |
期望绘制的图表样式为在同一画布中展示多组箱线图,同时标注成对比较的显著性结果。相关原始数据及模型详情如下:
data <- structure(list(PARTICIPANTS = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 20L, 20L, 20L, 20L, 21L, 21L, 21L, 21L), CONT_Y = c(19.44, 20.07, 19.21, 16.35, 11.37, 12.82, 19.42, 18.94, 19.59, 20.01, 19.7, 17.92, 18.78, 19.21, 19.27, 18.46, 19.52, 20.02, 16.19, 19.97, 13.83, 15.93, 14.79, 21.55, 18.8, 19.42, 19.27, 19.37, 17.14, 14.45, 17.63, 20.01, 20.28, 17.93, 19.36, 20.15, 16.06, 17.04, 19.16, 20.1, 16.44, 18.39, 18.01, 19.05, 18.04, 19.69, 19.61, 16.88, 19.02, 20.42, 18.27, 18.43, 18.08, 17.1, 19.98, 19.43, 19.71, 19.93, 20.11, 18.41, 20.31, 20.1, 20.38, 20.29, 13.6, 18.92, 19.05, 19.13, 17.75, 19.15, 20.19, 18.3, 19.43, 19.8, 19.83, 19.53, 16.14, 21.14, 17.37, 18.73, 16.51, 17.51, 17.06, 19.42 ), CATEGORIES = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L), .Label = c("A", "B"), class = "factor"), MY_GROUP = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L ), .Label = c("G1", "G2"), class = "factor")), row.names = c(NA, -84L), class = c("tbl_df", "tbl", "data.frame")) ### 重命名列: data <- data %>% rename(., YEAR = CATEGORIES)
解决方案
1. 整理成对比较数据
首先需要清理my_pairs中的缺失值,补全分组信息,并给比较类型分类,方便后续绘图:
library(dplyr) library(tidyr) my_pairs_clean <- my_pairs %>% mutate( # 补全组间比较的MY_GROUP信息 MY_GROUP = case_when( grepl("L1 - L2", contrast) ~ rep(c("G1", "G2"), 2), TRUE ~ MY_GROUP ), # 补全年份比较的YEAR信息 YEAR = case_when( grepl("YEAR2020 - YEAR2021", contrast) ~ rep(c("2020", "2021"), 2), TRUE ~ YEAR ), # 标记比较类型 comp_type = case_when( grepl("L1 - L2", contrast) ~ "组间比较", TRUE ~ "年份间比较" ) ) %>% drop_na()
2. 绘制带显著性标记的多箱线图
使用ggplot2绘制箱线图展示原始数据分布,同时用ggsignif添加成对比较的显著性标记(*代表p<0.05):
library(ggplot2) library(ggsignif) # 确保YEAR为字符类型 data$YEAR <- as.character(data$YEAR) # 绘制分面箱线图,整合两种比较类型 ggplot(data, aes(x = MY_GROUP, y = CONT_Y, fill = YEAR)) + geom_boxplot(position = position_dodge(width = 0.8), alpha = 0.7) + # 添加组间比较的显著性标记(按年份分面) geom_signif( data = my_pairs_clean %>% filter(comp_type == "组间比较"), aes(xmin = 1, xmax = 2, annotations = ifelse(p.value < 0.05, "*", "")), y_position = 22, tip_length = 0.01, position = position_dodge(width = 0.8) ) + # 添加年份间比较的显著性标记(按分组) geom_signif( data = my_pairs_clean %>% filter(comp_type == "年份间比较"), aes(xmin = c(1.2, 2.2), xmax = c(1.8, 2.8), annotations = ifelse(p.value < 0.05, "*", "")), y_position = 23, tip_length = 0.01 ) + facet_wrap(~ YEAR) + labs( title = "分组与年份的成对比较箱线图", x = "分组", y = "CONT_Y数值", fill = "年份" ) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
3. 可选:合并两个独立比较图
如果希望将两种比较类型的箱线图分开展示并合并在同一画布,可使用gridExtra包:
library(gridExtra) # 组间比较箱线图(按年份分组) p_group <- ggplot(data, aes(x = YEAR, y = CONT_Y, fill = MY_GROUP)) + geom_boxplot(position = position_dodge(width = 0.8), alpha = 0.7) + geom_signif( data = my_pairs_clean %>% filter(comp_type == "组间比较"), aes(xmin = c(1, 2), xmax = c(1.5, 2.5), annotations = ifelse(p.value < 0.05, "*", "")), y_position = 22, tip_length = 0.01, position = position_dodge(width = 0.8) ) + labs( title = "不同年份下的组间比较", x = "年份", y = "CONT_Y数值", fill = "分组" ) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5)) # 年份间比较箱线图(按分组) p_year <- ggplot(data, aes(x = MY_GROUP, y = CONT_Y, fill = YEAR)) + geom_boxplot(position = position_dodge(width = 0.8), alpha = 0.7) + geom_signif( data = my_pairs_clean %>% filter(comp_type == "年份间比较"), aes(xmin = c(1, 2), xmax = c(1.5, 2.5), annotations = ifelse(p.value < 0.05, "*", "")), y_position = 22, tip_length = 0.01, position = position_dodge(width = 0.8) ) + labs( title = "不同分组下的年份间比较", x = "分组", y = "CONT_Y数值", fill = "年份" ) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5)) # 合并两个图为一行 grid.arrange(p_group, p_year, ncol = 2)
内容的提问来源于stack exchange,提问作者Larissa Cury
相关产品推荐
相关产品推荐

