在 R 中的一个图中组合多个 forestplot 对象

Combine several forestplot object in one graph in R

一切都在问题中。我试图将 forestplot 对象转换为 ggplot 对象以使用 ggarrange() 函数,但它不起作用。我也尝试了 as.grob() 函数或 viewport(),但没有成功。 我在下面描述了我想合并在一个地块中的两个森林地块:

library(forestplot)
library(tidyverse)

#Estimate
est1=data.frame(model="multivariable model",
                variable=c("v1","v2","v3"),
                hr=c(1,2,3),
                low=c(0,1,2),
                high=c(2,3,4),
                p.value= rep(0.0123,3))
est2 = data.frame( model="univariable model",
                   variable=c("v1","v2","v3"),
                   hr=c(1,2,3),
                   low = c(0,1,2),
                   high=c(2,3,4),
                   p.value= rep(0.0123,3))


est= rbind(est1,est2) %>%
  mutate(variable= factor(variable,levels=c("v2","v3", "v1")),
                                 model= factor(model,levels=c("univariable model", "multivariable model"))) %>% arrange(variable,model)
#sheet4
forestplot_neutr = est

#Table text
tabletext <- cbind(c("Variables","v1","v2","v3"),
                   c('Baseline', c("low", "low", "low")),
                   c("Subcategory","high", "high", "high"), 
                   c("p-value", est %>% mutate(p.value=sub("0+$", "", as.character(signif(p.value,digits=2)))) %>%
                       group_by(variable) %>% summarize(p.value=str_c(p.value,collapse = "\n")) %>% pull(p.value)))

# adjust text size of forestplot
own <- fpTxtGp()
own$title$cex <-1
own <- fpTxtGp(label = gpar(cex=1.05), ticks = gpar(cex=1), summary=gpar(cex=1), xlab =gpar(cex=1), legend = gpar(cex=1),
               legend.title = gpar(cex=1), title = gpar(cex=1.5))

#Forest plot
p1 <- forestplot(tabletext, graph.pos=4, align = c("l","l","l","l"),
           legend =  c( "univariable", "multivariable"),
           legend_args = fpLegend(pos = list(x=.4, y=0.98), 
                                  gp=gpar(col="#CCCCCC", fill="#F9F9F9")),
           mean = cbind(c(NA,est %>% filter(model=="univariable model") %>% pull(hr)), 
                        c(NA,est %>% filter(model=="multivariable model") %>% pull(hr))),
           lower = cbind(c(NA,est %>% filter(model=="univariable model") %>% pull(low)),
                         c(NA,est %>% filter(model=="multivariable model") %>% pull(low))),
           upper = cbind(c(NA,est %>% filter(model=="univariable model") %>% pull(high)),
                         c(NA,est %>% filter(model=="multivariable model") %>% pull(high))),
           is.summary=c(TRUE,rep(FALSE,3)),
           txt_gp = own, 
           #hrzl_lines= gpar(lwd=1, columns=1:6, col = "#99999922", "leftbind"),
           title="",     
           xlab="Hazard Ratio",
           clip= c(0.1,6) , zero = 1, lineheight = unit(2.5,"cm"),boxsize= c(0.1),
           grid = structure(c(1), gp = gpar(lty = 1, col = "black")),
           graphwidth = unit(8, "cm"),
           colgap=unit(8,"mm"),lwd.ci=2, ci.vertices=TRUE, ci.vertices.height = 0.1,
           col=fpColors(box=c('gray', "black"), lines = c('gray', "black")),
           xticks = c(0.1,0.2,0.5,1,2,5,10,20),xlog=T) #5-12

#Second forest plot
p2 = p1

#How to combine forest plots?????????????????

这很棘手,因为 forestplot 对象实际上不是网格 grobs 或 ggplot 对象,而是包含“成分”的 S3 对象,这些“成分”仅在调用 print 时才“烘焙”成 grobs .有一种方法可以解决这个问题,那就是使用 ggplotifypatchwork 将它们转换为 grobs,将它们包装为 plot 对象,然后排列它们。

library(ggplotify)
library(patchwork)

p1 <- grid2grob(print(p1))
p2 <- grid2grob(print(p2))
p_both <- wrap_elements(p1) / wrap_elements(p2)
p_both

请注意,这些对象似乎也有以绝对单位测量的固定大小,而不是在 ggplot 中允许灵活纵横比的“npc”或“本地”单位。这意味着我必须使用 ggsave 保存生成的图,高度为 1024 像素,分辨率为 96 dpi,以便在单个图像中获得两个图。实际上,与在图形应用程序中将它们拼接在一起相比,在 R 中堆叠这些图没有任何好处。您可能想查看替代方案,例如 ggforest.