13使用 gtsummary 整理统计表

使用 gtsummary 的 tbl_summary 和 tbl_regression 整理描述统计与模型结果,并完成合并、格式化和导出。

2026-03-05
StatisticsRgtsummaryTablesRegression
本章目录 · 10

gtsummary 是用于整理描述统计和模型结果的 R 包。它将数据框或模型对象转换为结构统一、可以继续格式化和导出的表格。

本页关注这个包的主要入口和组合方式。统计方法如何选择、模型如何解释属于 Statistics 系列;具体 Table 1 的三线表、底纹和成品输出则由 Tessera 的 tableone 配方负责。

library(dplyr)
library(gtsummary)

data(trial)

基础描述表

table_1 <- trial |>
  tbl_summary(by = trt)

table_1

默认行为会根据变量类型选择统计量。正式分析中应显式指定关键规则:

table_1 <- trial |>
  tbl_summary(
    by = trt,
    include = c(age, marker, stage, grade, response),
    statistic = list(
      all_continuous() ~ "{median} ({p25}, {p75})",
      all_categorical() ~ "{n}/{N} ({p}%)"
    ),
    digits = all_continuous() ~ 1,
    label = list(
      age ~ "Age, years",
      marker ~ "Marker level",
      response ~ "Tumor response"
    ),
    missing = "ifany",
    missing_text = "Missing"
  )

关键参数

参数 决定内容
include 哪些变量进入表格
by 按哪个变量分组
type 连续、分类、二分类等变量角色
statistic 均值/SD、中位数/IQR、n/% 等格式
digits 显示精度
label 变量展示名称
percent 行、列或单元格百分比
missing 是否显示缺失行
sort 分类水平排列规则

数据存储为 numeric 不代表分析中一定是连续变量。例如编码为 0、1、2 的等级变量可能需要显式指定:

trial |>
  tbl_summary(
    by = trt,
    type = list(grade ~ "categorical")
  )

百分比的分母

trial |>
  tbl_summary(
    by = trt,
    include = c(grade, response),
    percent = "column"
  )

"column""row""cell" 表达不同分母。表头或脚注应让读者知道百分比如何计算。

缺失值

trial |>
  tbl_summary(
    by = trt,
    missing = "ifany",
    missing_text = "Missing",
    missing_stat = "{N_miss} ({p_miss}%)"
  )

展示缺失量不等于处理缺失。模型使用完整案例、多重插补或其他策略,都应在方法中另行说明。

添加总体、检验和差异

table_1 <- trial |>
  tbl_summary(by = trt) |>
  add_overall() |>
  add_n() |>
  add_p() |>
  add_q()

add_p() 的检验必须与变量类型、分布和设计匹配。必要时显式指定方法,而不是依赖自动选择:

trial |>
  tbl_summary(by = trt) |>
  add_p(
    test = list(
      age ~ "t.test",
      grade ~ "chisq.test"
    )
  )

基线表是否应展示 p 值取决于研究目的。随机试验中,基线差异的显著性检验通常不能替代对临床不平衡的判断。

修改表头与样式

table_1 |>
  modify_header(label ~ "**Variable**") |>
  modify_spanning_header(all_stat_cols() ~ "**Treatment group**") |>
  modify_caption("**Table 1. Participant characteristics**") |>
  bold_labels()

格式化应提升可读性,不应通过加粗显著 p 值让阈值取代效应大小和区间。

回归结果表

线性回归:

linear_fit <- lm(marker ~ age + grade + trt, data = trial)

linear_table <- tbl_regression(
  linear_fit,
  label = list(
    age ~ "Age, years",
    grade ~ "Tumor grade",
    trt ~ "Treatment"
  )
)

逻辑回归使用 exponentiate = TRUE 输出 OR:

logistic_fit <- glm(
  response ~ age + stage + grade + trt,
  data = trial,
  family = binomial()
)

logistic_table <- tbl_regression(
  logistic_fit,
  exponentiate = TRUE
)

对 Cox 模型,同一参数用于输出 HR:

library(survival)

cox_fit <- coxph(
  Surv(ttdeath, death) ~ age + grade + trt,
  data = trial
)

cox_table <- tbl_regression(
  cox_fit,
  exponentiate = TRUE
)

表头必须明确指数化估计是 OR、HR 还是其他比值。

单变量批量回归

univariable_cox <- trial |>
  select(ttdeath, death, age, grade, trt) |>
  tbl_uvregression(
    method = coxph,
    y = Surv(ttdeath, death),
    exponentiate = TRUE
  )

批量建模适合统一输出,但不能把大量单变量 p 值当作自动变量筛选器。

合并与堆叠

将两个模型并排:

tbl_merge(
  tbls = list(univariable_cox, cox_table),
  tab_spanner = c("**Univariable**", "**Multivariable**")
)

将结构相同的表纵向连接:

tbl_stack(list(table_a, table_b))

并排模型应说明协变量集合和样本量是否相同;否则系数变化可能来自调整,也可能来自进入模型的观测不同。

导出

library(flextable)

table_1 |>
  as_flex_table() |>
  save_as_docx(path = "table-1.docx")
table_1 |>
  as_gt() |>
  gt::gtsave("table-1.png")

生成表格后仍应核对原始频数、分母、参照水平、样本量、缺失和模型系数。自动格式化减少重复劳动,不减少统计责任。