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

使用gtsummary的tbl_merge合并tbl_summary与tbl_regression结果的问题

问题描述

我是长期浏览论坛的用户,首次发帖求助。我希望将多个通过tbl_summary()生成并经tbl_stack()堆叠的频率表,与多个通过tbl_regression()生成并经tbl_stack()堆叠的单变量逻辑回归表进行合并。

期望合并后的表格包含以下列:

  • (1) 二分类因变量名称
  • (2) 二分类自变量分层下因变量的频率百分比
  • (3) 回归分析的OR值
  • (4) 回归分析的95%置信区间

且表格行以回归分析的因变量命名。

我尝试了两种方式:

  • 先堆叠后合并:行按tbl_summary堆叠组和tbl_regression堆叠组分块,但存在错位空列
  • 先合并后堆叠:行交替出现tbl_summary和tbl_regression的内容,顺序混乱

问题根源在于tbl_summary表格保留了数据集中的因变量名称,而tbl_regression表格显示的是自变量名称。我对gt包不熟悉,推测它可能能解决此问题。恳请提供相关建议及示例代码!

示例代码如下:

library(gtsummary)
library(dplyr)
packageVersion("gtsummary")
#> '1.6.2'

ex <- trial %>%
  mutate(gradeI = case_when(grade == "I" ~ 1,
                            TRUE ~ 0),
         gradeII = case_when(grade == "II" ~ 1,
                            TRUE ~ 0),
         gradeIII = case_when(grade == "III" ~ 1,
                            TRUE ~ 0),
         agegp = case_when(age<47 ~ 0,
                            TRUE ~ 1))

t1 <- ex %>% select(gradeI, agegp) %>% tbl_summary(by = agegp)
t2 <- ex %>% select(gradeII, agegp) %>% tbl_summary(by = agegp)
t3 <- ex %>% select(gradeIII, agegp) %>% tbl_summary(by = agegp)

glm1 <- ex %>%
  select(gradeI, agegp) %>%
  tbl_uvregression(
    method = glm,
    y = gradeI,
    method.args = list(family = binomial),
    exponentiate = TRUE,
    label = list(agegp ~ "Grade I by age group"))
glm2 <- ex %>%
  select(gradeII, agegp) %>%
  tbl_uvregression(
    method = glm,
    y = gradeII,
    method.args = list(family = binomial),
    exponentiate = TRUE,
    label = list(agegp ~ "Grade II by age group"))
glm3 <- ex %>%
  select(gradeIII, agegp) %>%
  tbl_uvregression(
    method = glm,
    y = gradeIII,
    method.args = list(family = binomial),
    exponentiate = TRUE,
    label = list(agegp ~ "Grade II by age group"))

merge1 <- tbl_merge(tbls = list(t1, glm1),
          tab_spanner = c("**Tumor grade frequencies<br>by age group**", "**<br>Univariate regression**"))
merge2 <- tbl_merge(tbls = list(t2, glm2),
          tab_spanner = c("**Tumor grade frequencies<br>by age group**", "**<br>Univariate regression**"))
merge3 <- tbl_merge(tbls = list(t3, glm3),
          tab_spanner = c("**Tumor grade frequencies<br>by age group**", "**<br>Univariate regression**"))

tbl_stack(tbls = list(merge1, merge2, merge3))
解决方案

核心思路是先统一两个表格的行标识,调整列结构后合并单个因变量的频率表与回归表,最后堆叠所有结果。

以下是修正后的代码:

library(gtsummary)
library(dplyr)
packageVersion("gtsummary")

ex <- trial %>%
  mutate(gradeI = case_when(grade == "I" ~ 1, TRUE ~ 0),
         gradeII = case_when(grade == "II" ~ 1, TRUE ~ 0),
         gradeIII = case_when(grade == "III" ~ 1, TRUE ~ 0),
         agegp = case_when(age < 47 ~ 0, TRUE ~ 1))

# 处理频率表:设置行名为因变量名称,规范列头和注释
t1 <- ex %>% select(gradeI, agegp) %>% 
  tbl_summary(by = agegp, label = list(gradeI ~ "Grade I")) %>%
  modify_header(all_stat_cols() ~ "**Age Group {level}**") %>%
  modify_footnote(all_stat_cols() ~ "n (%)")

t2 <- ex %>% select(gradeII, agegp) %>% 
  tbl_summary(by = agegp, label = list(gradeII ~ "Grade II")) %>%
  modify_header(all_stat_cols() ~ "**Age Group {level}**") %>%
  modify_footnote(all_stat_cols() ~ "n (%)")

t3 <- ex %>% select(gradeIII, agegp) %>% 
  tbl_summary(by = agegp, label = list(gradeIII ~ "Grade III")) %>%
  modify_header(all_stat_cols() ~ "**Age Group {level}**") %>%
  modify_footnote(all_stat_cols() ~ "n (%)")

# 处理回归表:合并置信区间为一列,统一行名与频率表匹配
glm1 <- ex %>%
  select(gradeI, agegp) %>%
  tbl_uvregression(
    method = glm,
    y = gradeI,
    method.args = list(family = binomial),
    exponentiate = TRUE,
    include = agegp,
    label = list(gradeI ~ "Grade I")) %>%
  modify_header(estimate ~ "**OR**", conf.low ~ "**95% CI**") %>%
  modify_column_merge(columns = c(conf.low, conf.high), pattern = "{conf.low}, {conf.high}") %>%
  modify_rows(update = list(row_type = "label", row_label = "Grade I"))

glm2 <- ex %>%
  select(gradeII, agegp) %>%
  tbl_uvregression(
    method = glm,
    y = gradeII,
    method.args = list(family = binomial),
    exponentiate = TRUE,
    include = agegp,
    label = list(gradeII ~ "Grade II")) %>%
  modify_header(estimate ~ "**OR**", conf.low ~ "**95% CI**") %>%
  modify_column_merge(columns = c(conf.low, conf.high), pattern = "{conf.low}, {conf.high}") %>%
  modify_rows(update = list(row_type = "label", row_label = "Grade II"))

glm3 <- ex %>%
  select(gradeIII, agegp) %>%
  tbl_uvregression(
    method = glm,
    y = gradeIII,
    method.args = list(family = binomial),
    exponentiate = TRUE,
    include = agegp,
    label = list(gradeIII ~ "Grade III")) %>%
  modify_header(estimate ~ "**OR**", conf.low ~ "**95% CI**") %>%
  modify_column_merge(columns = c(conf.low, conf.high), pattern = "{conf.low}, {conf.high}") %>%
  modify_rows(update = list(row_type = "label", row_label = "Grade III"))

# 合并单个因变量的频率表与回归表,再堆叠所有结果
merge1 <- tbl_merge(tbls = list(t1, glm1), 
                    tab_spanner = c("**Tumor Grade Frequencies**", "**Univariate Regression**"))
merge2 <- tbl_merge(tbls = list(t2, glm2), 
                    tab_spanner = c("**Tumor Grade Frequencies**", "**Univariate Regression**"))
merge3 <- tbl_merge(tbls = list(t3, glm3), 
                    tab_spanner = c("**Tumor Grade Frequencies**", "**Univariate Regression**"))

# 移除重复跨表头,统一整体列头
final_table <- tbl_stack(tbls = list(merge1, merge2, merge3), 
                         group_header = NULL) %>%
  modify_spanning_header(everything() ~ NA) %>%
  modify_header(
    label ~ "**Dependent Variable**",
    starts_with("stat_") ~ "**Age Group {level} (n%)**",
    estimate ~ "**OR**",
    conf.low ~ "**95% CI**"
  )

final_table

代码说明

  • 频率表调整:通过label参数直接将行名设置为因变量名称,用modify_header和modify_footnote规范列名和统计量注释
  • 回归表调整:使用modify_column_merge将置信区间的上下限合并为一列,modify_rows确保行名与频率表完全匹配
  • 合并与堆叠:先合并单个因变量的频率表和回归表,再堆叠所有结果,最后通过modify_spanning_header移除重复的跨表头,统一设置整体列头,满足需求中的列结构要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:47:56