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

如何合并R中adjustedCurves包生成的50个校正生存风险表?

解决多重插补后风险表提取、合并与可视化问题

一、提取adjustedsurv()中的风险表

首先要确保调用adjustedsurv()时开启风险表返回,修改你的分析代码:

library(mice)
library(survival)
library(adjustedCurves)
library(data.table)
library(gt)

# 假设imp是你生成的多重插补对象
adj_surv_list <- lapply(1:50, function(m) {
  dat <- complete(imp, m)
  # 计算IPtW权重
  ps_model <- glm(trt ~ cov1 + cov2 + cov3, data = dat, family = binomial)
  dat$iptw <- weights(ps_model, type = "ipw")
  # 拟合加权Cox模型
  cox_model <- coxph(Surv(time, event) ~ trt, data = dat, weights = iptw)
  # 生成校正曲线时,必须设置return_risktable=TRUE
  adj_surv <- adjustedsurv(data = dat,
                           variable = "trt",
                           ev_time = "time",
                           event = "event",
                           method = "iptw",
                           outcome_model = cox_model,
                           return_risktable = TRUE)
  adj_surv
})

# 提取所有插补数据集的风险表
risktables_list <- lapply(adj_surv_list, function(x) {
  rt <- x$risktable
  rt$imp_num <- m # 标记插补编号
  rt
})

# 合并为一个大数据表
all_risktables <- rbindlist(risktables_list)

二、用Rubin法则合并风险表

针对风险表中的n_at_risk(风险人数)和n_events(事件数),按时间点、治疗组分组合并:

m <- 50 # 插补数据集数量

merged_risktable <- all_risktables[, .(
  # 点估计取各插补数据集的均值
  n_at_risk = mean(n_at_risk),
  n_events = mean(n_events),
  # 计算标准误与95%置信区间(基于t分布)
  se_at_risk = sd(n_at_risk)/sqrt(m),
  se_events = sd(n_events)/sqrt(m),
  ci_lower_at_risk = n_at_risk - qt(0.975, df = m-1)*se_at_risk,
  ci_upper_at_risk = n_at_risk + qt(0.975, df = m-1)*se_at_risk,
  ci_lower_events = n_events - qt(0.975, df = m-1)*se_events,
  ci_upper_events = n_events + qt(0.975, df = m-1)*se_events
), by = .(time, strata)]

# 格式化输出列
merged_risktable <- merged_risktable[, .(
  time = round(time, 1),
  treatment = strata,
  n_at_risk = round(n_at_risk),
  n_at_risk_ci = paste0("[", round(ci_lower_at_risk), ", ", round(ci_upper_at_risk), "]"),
  n_events = round(n_events),
  n_events_ci = paste0("[", round(ci_lower_events), ", ", round(ci_upper_events), "]")
)]

三、用data.table自行计算风险表

如果需要手动计算,基于校正生存概率推导:

# 提取所有插补数据集的校正生存数据
adj_data_list <- lapply(adj_surv_list, function(x) x$adj)
all_adj_data <- rbindlist(adj_data_list, idcol = "imp_num")

# 计算每个插补数据集的初始加权样本量
initial_n <- all_adj_data[, .(initial_weighted_n = sum(weights)), by = .(imp_num, strata)]
all_adj_data <- merge(all_adj_data, initial_n, by = c("imp_num", "strata"))

# 推导风险人数与事件数
all_adj_data <- all_adj_data[order(imp_num, strata, time)]
all_adj_data[, surv_prev := shift(surv, fill = 1), by = .(imp_num, strata)]
all_adj_data[, n_at_risk := initial_weighted_n * surv]
all_adj_data[, n_events := initial_weighted_n * (surv_prev - surv)]
all_adj_data[, cum_events := cumsum(n_events), by = .(imp_num, strata)]

# 后续合并步骤同第二部分

四、用gt包可视化合并后的风险表

gt可以轻松生成美观的分层风险表:

gt_table <- merged_risktable %>%
  gt(groupname_col = "treatment") %>%
  tab_header(title = "校正后风险表(多重插补合并)",
             subtitle = "基于IPtW Cox模型,50个插补数据集合并结果") %>%
  cols_label(
    time = "时间",
    n_at_risk = "风险人数",
    n_at_risk_ci = "95%置信区间",
    n_events = "事件数",
    n_events_ci = "95%置信区间"
  ) %>%
  fmt_number(columns = c(n_at_risk, n_events), decimals = 0) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_row_groups()
  ) %>%
  tab_options(
    table.width = pct(90),
    row_group.border.top = border(width = 2),
    row_group.border.bottom = border(width = 1)
  )

# 输出表格
gt_table

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:00:59