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