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

基于metafor的亚组随机效应森林图绘制问题求助

解决metafor包亚组森林图元素定位与亚组权重总和显示问题

一、亚组标题/汇总值/多边形的自适应定位

靠order和pos硬编码位置确实容易受图表尺寸影响,试试这两种更稳的方法:

1. 手动锚定位置(精准可控)

先统计各亚组的研究数量,给亚组标题、汇总元素设置固定的y轴位置,提前预留画布空间:

# 假设数据已按亚组分组,先统计各亚组研究数
sub_counts <- table(dat$subgroup)
total_studies <- sum(sub_counts)

# 绘制森林图时预留顶部空间放亚组标题
forest(res, 
       ylim = c(-2, total_studies + length(sub_counts)*2 + 2), # 按亚组数量留空间
       order = dat$subgroup,
       showweights = TRUE)

# 逐个添加亚组标题和汇总信息
current_y <- total_studies + length(sub_counts)*2
for (sub in names(sub_counts)) {
  # 添加亚组标题
  text(par("usr")[1] - 0.1, current_y, paste0("亚组: ", sub), pos = 4, font = 2)
  # 拟合当前亚组的*随机效应模型*
  sub_mod <- rma.uni(yi, vi, data = dat[dat$subgroup == sub, ], method = "REML")
  # 添加亚组汇总多边形
  addpoly(sub_mod, row = current_y - 1, col = "darkred", border = "black")
  # 添加汇总值文本
  text(sub_mod$b, current_y - 1, 
       paste0("RE: ", round(sub_mod$b, 2), " [", round(sub_mod$ci.lb, 2), ", ", round(sub_mod$ci.ub, 2), "]"), 
       pos = 4)
  # 更新y轴位置,跳过当前亚组的研究行
  current_y <- current_y - sub_counts[sub] - 2
}

2. 动态获取绘图坐标(自适应窗口)

用par("usr")获取当前绘图区域的坐标范围,基于这个范围计算元素位置,完全不受窗口缩放影响:

# 拟合含亚组的*随机效应模型*
res_sub <- rma.uni(yi, vi, mods = ~ subgroup - 1, method = "REML", data = dat)

# 绘制森林图,自动拆分亚组
forest(res_sub, subgroup = dat$subgroup, showweights = TRUE)

# 获取绘图区域的坐标边界
usr <- par("usr")
y_top <- usr[4]

# 遍历亚组添加标题,动态计算位置
for (sub in names(sub_counts)) {
  # 找到当前亚组第一个研究的y位置
  sub_first_y <- which(dat$subgroup == sub)[1] + length(sub_counts) # 亚组标题行偏移
  text(usr[1] - 0.1, y_top - (length(sub_counts) - which(names(sub_counts) == sub))*2, 
       paste0("亚组: ", sub), pos = 4, font = 2)
}

二、显示亚组的权重总和

1. 手动计算并标注

提取每个研究的权重,按亚组求和后直接添加到亚组标题旁:

# 提取所有研究的权重(基于主模型)
dat$wts <- weights(res)

# 按亚组汇总权重
sub_total_wts <- tapply(dat$wts, dat$subgroup, sum)

# 在亚组标题中加入权重信息
current_y <- total_studies + length(sub_counts)*2
for (sub in names(sub_total_wts)) {
  text(par("usr")[1] - 0.1, current_y, 
       paste0("亚组: ", sub, " (总权重: ", round(sub_total_wts[sub], 1), "%)"), 
       pos = 4, font = 2)
  current_y <- current_y - sub_counts[sub] - 2
}

2. 结合森林图权重列添加

开启showweights = TRUE显示单个研究权重后,在亚组汇总行的右侧标注总权重:

forest(res_sub, subgroup = dat$subgroup, showweights = TRUE)

# 获取亚组汇总行的y位置
sub_sum_rows <- total_studies + 1 - cumsum(sub_counts) + length(sub_counts)

# 逐个添加亚组总权重
for (i in seq_along(sub_sum_rows)) {
  text(usr[2] + 0.1, sub_sum_rows[i], 
       paste0("总权重: ", round(sub_total_wts[i], 1), "%"), 
       pos = 2, cex = 0.9)
}

核心提示

  • 绘图前务必设置合适的ylim,避免标题、汇总元素被裁切或重叠
  • 所有位置计算基于par("usr")返回的当前绘图坐标,能彻底解决窗口尺寸变动导致的错位问题
  • 亚组的汇总多边形必须基于单独拟合的随机效应模型生成,确保结果准确

内容的提问来源于stack exchange,提问作者jacerl980

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 00:34:59