You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调整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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:35:26