如何调整R的forestplot()参数实现森林图对齐堆叠?
实现forestplot多图对齐堆叠
要让线性模型(零效应线为0)和Logistic模型(零效应线为1)的森林图左侧文本区对齐、绘图区零效应线对齐,核心是固定文本区域宽度和统一绘图区的零效应位置,以下是修改后的可运行方案:
修改后的完整代码
library(forestplot) library(grid) # 原始数据与模型拟合 cohort <- data.frame(Age = c(43, 39, 34, 55, 70, 59, 44, 83, 76, 44, 75, 60, 62, 50, 44, 40, 41, 42, 37, 35, 55, 46), Status = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L), levels = c("-", "+"), class = "factor"), Group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), levels = c("1","2"), class = "factor")) age.lm <- lm(Age ~ Group, data = cohort) status.lm <- glm(Status ~ Group, data = cohort, family=binomial(link=logit)) age.data <- summary(age.lm)$coefficients[2,] status.data <- summary(status.lm)$coefficients[2,] age.data <- rbind(c(0,0,0,1,"Group 1", "n=15"), c(age.data[1], age.data[1]-age.data[2]*1.95, age.data[1]+age.data[2]*1.95, age.data[4], "Group 2", "n=7")) status.data <- rbind(c(0,0,0,1,"Group 1", "[+13,-2]"), c(status.data[1], status.data[1]-status.data[2]*1.95, status.data[1]+status.data[2]*1.95, status.data[4], "Group 2", "[+2,-5]")) colnames(age.data) <- c("mean","lower","upper","p-val","labeltext","numbers") colnames(status.data) <- c("mean","lower","upper","p-val","labeltext","numbers") age.data <- data.frame(age.data) status.data <- data.frame(status.data) age.data$mean <- as.numeric(age.data$mean) age.data$lower <- as.numeric(age.data$lower) age.data$upper <- as.numeric(age.data$upper) status.data$mean <- exp(as.numeric(status.data$mean)) status.data$lower <- exp(as.numeric(status.data$lower)) status.data$upper <- exp(as.numeric(status.data$upper)) # 绘制年龄森林图(线性模型) age.plot <- forestplot(age.data, labeltext = c(labeltext, numbers), boxsize = 0.1, xlog = FALSE, clip = c(-20, 20), xticks = c(-20, -10, 0, 10, 20), txt_gp = fpTxtGp(ticks = gpar(cex=1)), align = c("l", "c", "l"), graph.pos = 3, # 固定绘图区起始位置,确保文本区宽度一致 xlab = "年龄差异(线性模型)") # 绘制状态森林图(Logistic模型) status.plot <- forestplot(status.data, labeltext = c(labeltext, numbers), boxsize = 0.1, xlog = TRUE, clip = c(1/100, 100), xticks = c(0.01, 0.1, 1, 10, 100), # 用原始尺度刻度,匹配零效应线位置 xticks.digits = 2, txt_gp = fpTxtGp(ticks = gpar(cex=1)), align = c("l", "c", "l"), graph.pos = 3, # 与年龄图保持相同的文本区宽度 xlab = "比值比(Logistic模型)") # 垂直堆叠两幅图 grid.newpage() pushViewport(viewport(layout = grid.layout(2, 1))) print(age.plot, vp = viewport(layout.pos.row = 1, layout.pos.col = 1)) print(status.plot, vp = viewport(layout.pos.row = 2, layout.pos.col = 1))
关键调整说明
graph.pos = 3:强制绘图区从第3列开始(对应labeltext的2列文本),让两幅图的左侧文本区域宽度完全一致,避免文本长度差异导致绘图区偏移。- Logistic模型刻度优化:将
xticks设为原始尺度值(0.01、0.1、1、10、100),配合xlog=TRUE,零效应线(1)会和线性模型的零效应线(0)在垂直方向严格对齐。 - grid布局堆叠:用
grid包的视口功能将两幅图垂直拼接,保证整体视觉整洁。
内容的提问来源于stack exchange,提问作者user36196
相关产品推荐
相关产品推荐

