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

如何对多重插补数据集的GAM拟合结果进行可视化?

多重插补后GAM模型的合并绘图解决方案

我正在处理含缺失值的数据集,用R的mice包做多重插补,之后用mgcv包在插补后的数据集上拟合广义可加模型(GAM)。我想绘制所有插补数据集上的模型整体拟合结果,但不知道怎么合并各插补数据集的绘图结果。

现有尝试代码

单独绘制各插补模型的拟合图

library(mgcv)
library(mice)
library(ggplot2)

# 设置随机种子保证可复现
set.seed(123)

# 生成模拟数据集
n <- 200
data <- data.frame(
  outcome = rnorm(n),
  exposure = rnorm(n),
  covariate1 = sample(0:1, n, replace = TRUE),
  covariate2 = rnorm(n, 40, 2),
  covariate3 = rnorm(n, 30, 1),
  covariate4 = sample(0:1, n, replace = TRUE),
  covariate5 = sample(0:1, n, replace = TRUE)
)
# 人为添加缺失值
data[sample(1:n, 50), "exposure"] <- NA
data[sample(1:n, 50), "covariate1"] <- NA

# 执行多重插补
imp <- mice(data, m = 5, method = 'pmm', seed = 123)
# 在插补数据集上拟合GAM模型
model <- with(imp, gam(outcome ~ s(exposure) + covariate1 + covariate2 + covariate3 + covariate4 + covariate5, method = 'REML'))

# 单独绘制每个插补模型的拟合图
fitted_models <- model$analyses
par(mfrow = c(2, 3))  # 调整布局以容纳所有图
for (i in 1:length(fitted_models)) {
  plot(fitted_models[[i]], shade = TRUE, rug = TRUE, residuals = TRUE, pch = 1, cex = 1, main = paste("插补数据集", i))
}

上述代码只能生成每个插补数据集的单独拟合图,无法得到合并后的整体结果。

尝试合并模型但失败的代码

# pooled.fit <- pool(model)
# plot.gam(pooled.fit)

pool()函数返回的是合并后的模型参数汇总,不是可直接用plot.gam()绘制的GAM对象,因此无法直接绘图。

解决方案:合并插补模型的平滑项拟合结果并绘图

要得到所有插补数据集上的整体拟合结果,需要提取每个插补模型中平滑项的拟合值、置信区间,然后计算它们的均值和合并后的置信区间,最后用ggplot2绘制。

完整代码

library(mgcv)
library(mice)
library(ggplot2)
library(dplyr)

# 设置随机种子
set.seed(123)

# 生成模拟数据集(同之前)
n <- 200
data <- data.frame(
  outcome = rnorm(n),
  exposure = rnorm(n),
  covariate1 = sample(0:1, n, replace = TRUE),
  covariate2 = rnorm(n, 40, 2),
  covariate3 = rnorm(n, 30, 1),
  covariate4 = sample(0:1, n, replace = TRUE),
  covariate5 = sample(0:1, n, replace = TRUE)
)
data[sample(1:n, 50), "exposure"] <- NA
data[sample(1:n, 50), "covariate1"] <- NA

# 多重插补与模型拟合
imp <- mice(data, m = 5, method = 'pmm', seed = 123)
model <- with(imp, gam(outcome ~ s(exposure) + covariate1 + covariate2 + covariate3 + covariate4 + covariate5, method = 'REML'))

# 提取每个插补模型的平滑项结果
smooth_results <- lapply(model$analyses, function(gam_mod) {
  # 提取s(exposure)的平滑项拟合数据(不直接绘图)
  smooth_dat <- plot(gam_mod, select = 1, seWithMean = TRUE, plot = FALSE)
  # 转换为数据框并添加插补编号
  data.frame(
    exposure = smooth_dat$x,
    fit = smooth_dat$fit,
    se = smooth_dat$se,
    lower = smooth_dat$fit - 1.96 * smooth_dat$se,
    upper = smooth_dat$fit + 1.96 * smooth_dat$se,
    imputation = as.character(which(model$analyses == gam_mod))
  )
})

# 合并所有插补数据集的结果
combined_smooth <- bind_rows(smooth_results)

# 按Rubin规则计算合并后的均值和置信区间
pooled_smooth <- combined_smooth %>%
  group_by(exposure) %>%
  summarize(
    mean_fit = mean(fit),
    # 计算合并标准误:综合插补内和插补间变异
    within_var = mean(se^2),
    between_var = var(fit),
    m = length(model$analyses),
    pooled_se = sqrt(within_var + between_var + between_var/m),
    lower = mean_fit - 1.96 * pooled_se,
    upper = mean_fit + 1.96 * pooled_se
  )

# 绘制合并后的拟合图
ggplot(pooled_smooth, aes(x = exposure, y = mean_fit)) +
  # 可选:添加各插补模型的拟合曲线用于对比
  geom_line(data = combined_smooth, aes(group = imputation), color = "gray", alpha = 0.5) +
  # 添加合并后的均值拟合曲线
  geom_line(color = "red", linewidth = 1) +
  # 添加合并后的置信区间
  geom_ribbon(aes(ymin = lower, ymax = upper), fill = "red", alpha = 0.2) +
  # 添加原始数据的rug图展示分布
  geom_rug(data = data, aes(x = exposure), sides = "b", alpha = 0.5) +
  labs(title = "多重插补后GAM模型的合并拟合结果",
       x = "暴露变量",
       y = "平滑项拟合值") +
  theme_minimal()

代码说明

  1. 提取平滑项数据:用plot(gam_mod, plot = FALSE)获取每个GAM模型中s(exposure)的拟合值、标准误等数据,避免直接生成单独绘图。
  2. 合并结果:将所有插补模型的平滑项数据合并到一个数据框中,便于后续计算。
  3. 计算合并统计量:采用Rubin规则计算合并后的拟合均值和标准误,同时考虑插补内和插补间的变异,得到更可靠的置信区间。
  4. 可视化:用ggplot2绘制合并后的核心拟合曲线与置信区间,可选添加各插补模型的拟合曲线作为对比,同时用rug图展示原始数据的分布情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 09:14:52