在R中用ggarrange组合箱线图报错:无法将list转为grob
问题描述
尝试用ggarrange将三张箱线图组合到一张图中时,重复出现报错:Warning: Cannot convert object of class list into a grob。
绘制箱线图的代码如下:
clr <- hcl.colors(length(unique(df6$Q8)), alpha=.5) blr <- hcl.colors(length(unique(df6$Q8)), alpha=1) A <- boxplot(AI ~ Q8,data=df6, xlab="walking ability", ylab="% active", col=clr, border=blr) corr <- with(df6, cor.test(AI, Q8))[c('estimate', 'conf.int')] legend('topleft', legend=bquote(rho ==.(signif(corr[[1]], 2))~'['*.(signif(corr[[2]][1], 2))*','~.(signif(corr[[2]][2], 2))*']'), bty='n') clr <- hcl.colors(length(unique(df6$Q8)), alpha=.5) blr <- hcl.colors(length(unique(df6$Q8)), alpha=1) B <- boxplot(activity ~ Q8,data=df6, xlab="Walking ability", ylab="% active", col=clr, border=blr) corr <- with(df6, cor.test(activity, Q8))[c('estimate', 'conf.int')] legend('topleft', legend=bquote(rho ==.(signif(corr[[1]], 2))~'['*.(signif(corr[[2]][1], 2))*','~.(signif(corr[[2]][2], 2))*']'), bty='n') clr <- hcl.colors(length(unique(df6$Q8)), alpha=.5) blr <- hcl.colors(length(unique(df6$Q8)), alpha=1) C <- boxplot(ZIM_SD ~ Q8,data=df6, xlab="Walking ability", ylab="Zero inflated model", col=clr, border=blr) corr <- with(df6, cor.test(ZIM_SD, Q8))[c('estimate', 'conf.int')] legend('topleft', legend=bquote(rho ==.(signif(corr[[1]], 2))~'['*.(signif(corr[[2]][1], 2))*','~.(signif(corr[[2]][2], 2))*']'), bty='n')
用于组合图形的代码:
ggarrange(A, # First row with line plot # Second row with box and dot plots ggarrange(B, C, ncol = 2, labels = c("", "")), nrow = 2, labels = "" # Label of the line plot )
报错原因
ggarrange(来自ggpubr包)是为ggplot2对象设计的图形组合工具,而base R的boxplot()函数返回的不是ggplot对象,而是包含箱线图统计信息的列表(class为list),无法被ggarrange识别为可组合的图形元素,因此触发报错。
解决方案
以下提供两种可行的解决思路:
方案1:使用base R布局函数组合图形
如果想继续使用base R的boxplot,可以用layout()指定多图布局,直接按顺序绘制即可:
# 设置布局:第一行1个图,第二行2个图 layout(matrix(c(1,2,3), nrow=2, byrow=TRUE)) # 绘制图A clr <- hcl.colors(length(unique(df6$Q8)), alpha=.5) blr <- hcl.colors(length(unique(df6$Q8)), alpha=1) boxplot(AI ~ Q8,data=df6, xlab="walking ability", ylab="% active", col=clr, border=blr) corr <- with(df6, cor.test(AI, Q8))[c('estimate', 'conf.int')] legend('topleft', legend=bquote(rho ==.(signif(corr[[1]], 2))~'['*.(signif(corr[[2]][1], 2))*','~.(signif(corr[[2]][2], 2))*']'), bty='n') # 绘制图B clr <- hcl.colors(length(unique(df6$Q8)), alpha=.5) blr <- hcl.colors(length(unique(df6$Q8)), alpha=1) boxplot(activity ~ Q8,data=df6, xlab="Walking ability", ylab="% active", col=clr, border=blr) corr <- with(df6, cor.test(activity, Q8))[c('estimate', 'conf.int')] legend('topleft', legend=bquote(rho ==.(signif(corr[[1]], 2))~'['*.(signif(corr[[2]][1], 2))*','~.(signif(corr[[2]][2], 2))*']'), bty='n') # 绘制图C clr <- hcl.colors(length(unique(df6$Q8)), alpha=.5) blr <- hcl.colors(length(unique(df6$Q8)), alpha=1) boxplot(ZIM_SD ~ Q8,data=df6, xlab="Walking ability", ylab="Zero inflated model", col=clr, border=blr) corr <- with(df6, cor.test(ZIM_SD, Q8))[c('estimate', 'conf.int')] legend('topleft', legend=bquote(rho ==.(signif(corr[[1]], 2))~'['*.(signif(corr[[2]][1], 2))*','~.(signif(corr[[2]][2], 2))*']'), bty='n') # 恢复默认布局 layout(1)
方案2:改用ggplot2绘制箱线图,再用ggarrange组合
将箱线图改为ggplot2语法生成的对象,即可正常使用ggarrange组合。先定义通用函数减少重复代码:
library(ggplot2) library(ggpubr) # 定义生成带相关系数标注的箱线图的函数 create_boxplot <- function(data, x_var, y_var, x_label, y_label) { # 计算相关系数与置信区间 corr <- cor.test(data[[y_var]], data[[x_var]]) rho <- signif(corr$estimate, 2) ci_low <- signif(corr$conf.int[1], 2) ci_high <- signif(corr$conf.int[2], 2) corr_label <- bquote(rho == .(rho) ~ '[' * .(ci_low) * ',' ~ .(ci_high) * ']') # 生成颜色向量 n_groups <- length(unique(data[[x_var]])) clr <- hcl.colors(n_groups, alpha=.5) blr <- hcl.colors(n_groups, alpha=1) # 绘制ggplot箱线图 ggplot(data, aes(x = .data[[x_var]], y = .data[[y_var]])) + geom_boxplot(fill = clr, color = blr) + labs(x = x_label, y = y_label) + theme_bw() + annotate("text", x = 1, y = max(data[[y_var]], na.rm=TRUE), label = as.character(corr_label), hjust=0, vjust=1) } # 生成三个箱线图对象 A <- create_boxplot(df6, "Q8", "AI", "walking ability", "% active") B <- create_boxplot(df6, "Q8", "activity", "Walking ability", "% active") C <- create_boxplot(df6, "Q8", "ZIM_SD", "Walking ability", "Zero inflated model") # 使用ggarrange组合图形 ggarrange(A, ggarrange(B, C, ncol = 2), nrow = 2)
内容的提问来源于stack exchange,提问作者Data miner123
相关产品推荐
相关产品推荐

