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

使用gtsummary为调查设计对象生成自定义统计表格遇阻求助

解决gtsummary处理Survey Design对象生成风险差表格的问题

步骤1:修正风险差计算函数

原函数存在多分类因变量未转换、公式错误、硬编码目标类别三个核心问题,以下是修正后的灵活版本:

library(tidyverse)
library(gtsummary)
library(srvyr)
library(marginaleffects)
library(scales)

# 修正后的风险差计算函数
rdiff <- function(data, var, by, target_category) {
  # 将目标类别转换为二分类变量
  data_v <- data %>%
    mutate(v = as.numeric(.data[[var]] == target_category))
  
  # 重新构建survey design对象
  svy_dat <- data_v %>%
    as_survey_design(ids = cluster)
  
  # 拟合二分类调查模型(用身份链接直接计算风险差)
  model <- svyglm(
    formula = v ~ .data[[by]], 
    design = svy_dat, 
    family = binomial(link = "identity")
  )
  
  # 计算组间风险差(第二组 - 第一组)
  rd_obj <- avg_comparisons(
    model,
    variables = all_of(by),
    comparison = "pairwise",
    conf_level = 0.95
  )
  
  # 格式化为百分比+置信区间
  est <- style_sigfig(rd_obj$estimate * 100)
  l_ci <- style_sigfig(rd_obj$conf.low * 100)
  u_ci <- style_sigfig(rd_obj$conf.high * 100)
  
  str_glue("{est} ({l_ci}, {u_ci})")
}

步骤2:生成基础汇总表格

使用tbl_svysummary生成带置信区间的分组比例和总计列:

# 复用你的示例数据
set.seed(123) 
n <- 800
dat <- data.frame(id=1:n, 
                  group.var=rep(LETTERS[1:2], n/2),
                  age=sample(18:48, n, replace=TRUE),
                  var1=factor(sample(paste("Category", rep(1:5, 1)), n, replace=TRUE)),
                  var2=factor(sample(paste("Property", rep(1:2, 1)), n, replace=TRUE)),
                  var3=factor(sample(paste("Source", rep(1:3, 1)), n, replace=TRUE)),
                  var4=rnorm(n),
                  cluster=factor(sample(paste("Cluster", rep(1:26, 1)), n, replace=TRUE)))

svy.dat <- dat %>% as_survey_design(ids = cluster)

# 生成基础分组汇总表格
base_tbl <- svy.dat %>%
  tbl_svysummary(
    by = group.var,
    include = c(var1, var2, var3),
    type = all_categorical() ~ "categorical",
    statistic = all_categorical() ~ "{p}% ({ci})", # 显示百分比+95%CI
    missing = "no"
  ) %>%
  add_overall(label = "总计") # 添加总计列

步骤3:添加风险差列

自定义统计函数,将风险差整合到gtsummary表格中:

# 适配gtsummary的统计函数:为每个类别计算风险差
stat_risk_difference <- function(data, variable, by, ...) {
  # 提取当前行的目标类别(移除变量名前缀)
  target_category <- data$label[1] %>% str_remove(paste0(variable, ": "))
  
  # 调用修正后的rdiff函数
  rd_result <- rdiff(data = data, var = variable, by = by, target_category = target_category)
  
  # 返回符合gtsummary要求的数据框格式
  tibble(stat = rd_result)
}

# 添加风险差列到基础表格
final_tbl <- base_tbl %>%
  add_stat(
    fns = list(all_categorical() ~ stat_risk_difference),
    by = "group.var",
    label = "风险差 (B-A, 95% CI)"
  ) %>%
  # 调整表头格式
  modify_header(
    stat_1 = "组A: 比例 (95% CI)",
    stat_2 = "组B: 比例 (95% CI)",
    stat_overall = "总计: 比例 (95% CI)",
    stat_added = "风险差 (B-A, 95% CI)"
  ) %>%
  # 优化表格样式
  modify_spanning_header(c(stat_1, stat_2) = "分组统计") %>%
  modify_caption("分类变量分组比例及组间风险差(基于复杂调查设计)")

关键修正说明

  1. 二分类转换:风险差是二结局统计量,必须将多分类变量的目标类别转为二分类变量,才能正确计算组间差异。
  2. 模型链接函数:使用binomial(link = "identity")直接拟合风险模型,避免logit转换反变换带来的偏差。
  3. 动态变量引用:用.data[[var]]和.data[[by]]实现动态公式,解决原函数硬编码的问题,支持任意变量和分组。
  4. gtsummary整合:通过add_stat将自定义统计量嵌入表格,保持gtsummary的格式一致性和可扩展性。

运行final_tbl即可得到包含分组比例(带CI)、总计、风险差(带CI)的目标表格。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:00:00