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

临床研究统计:如何纵向合并多变量交叉表与统计表格

问题:纵向合并多个交叉表并修复总计行缺失问题

我正在开展临床研究的统计分析,需要在同一张表格里同时呈现:

  • 多个交叉表(类似SPSS CROSSTABS输出,可通过descr::CrossTabs等包复现),带列总计
  • 连续变量的中位数(百分位数)及Wilcoxon-Mann-Whitney检验P值

目前用gtsummary包的tbl_cross生成了多个交叉表,但tbl_merge(v)会把表格横向并排,而且总计行存在缺失值适配问题,希望改成纵向合并的形式。现有代码如下:

set.seed(123)
member <- sample(c("Yes", "No"), 100, replace = TRUE)
author <- sample(c("Yes", "No"), 100, replace = TRUE)
review <- sample(0:10, 100, replace = TRUE)
publish <- sample(0:10, 100, replace = TRUE)
pay <- sample(0:10, 100, replace = TRUE)
df <- data.frame(member, author, review, 
                 publish, pay) |>
  dplyr::mutate(across(c(review, publish, pay),
                       ~cut(.,
                            breaks = c(-Inf, 4.5, 5.5, Inf),
                            labels = c("No", "Maybe", "Yes"),
                            include.lowest = TRUE), 
                       .names = "{.col}_group"))

cv <- c("review_group", "publish_group", "pay_group")
v <- map(
  cv,
  ~ tbl_cross(data = df, row = .x, col = member,
              missing = "no", percent = "column") |>
    add_p(pvalue_fun = label_style_pvalue(digits = 3))
)

tbl_merge(v)

解决方案:用tbl_stack替代tbl_merge并调整总计行

核心是改用gtsummary的tbl_stack()实现纵向合并,同时调整表格结构修复总计行问题,完整代码如下:

library(gtsummary)
library(dplyr)
library(purrr)

set.seed(123)
member <- sample(c("Yes", "No"), 100, replace = TRUE)
author <- sample(c("Yes", "No"), 100, replace = TRUE)
review <- sample(0:10, 100, replace = TRUE)
publish <- sample(0:10, 100, replace = TRUE)
pay <- sample(0:10, 100, replace = TRUE)
df <- data.frame(member, author, review, 
                 publish, pay) |>
  dplyr::mutate(across(c(review, publish, pay),
                       ~cut(.,
                            breaks = c(-Inf, 4.5, 5.5, Inf),
                            labels = c("No", "Maybe", "Yes"),
                            include.lowest = TRUE), 
                       .names = "{.col}_group"))

# 定义生成单个交叉表的函数,包含总计行和P值
create_crosstab <- function(var_name) {
  tbl_cross(data = df, row = all_of(var_name), col = member,
            missing = "no", percent = "column") |>
    # 确保列总计正常显示
    modify_header(all_cols() ~ "**{col}**") |>
    add_p(pvalue_fun = label_style_pvalue(digits = 3)) |>
    # 为每个表格添加变量名作为标题行
    modify_table_styling(
      location = "header",
      columns = label,
      rows = TRUE,
      fmt_fun = function(x) paste0("**", var_name, "**")
    )
}

cv <- c("review_group", "publish_group", "pay_group")
# 批量生成所有交叉表
v <- map(cv, create_crosstab)

# 纵向合并所有表格
tbl_stack(v)

关键说明

  1. 替换合并逻辑:用tbl_stack()替代横向合并的tbl_merge(),直接实现多个表格的纵向堆叠
  2. 修复总计行:通过modify_header()确保列总计正常渲染,避免缺失值适配问题
  3. 统一表格样式:自定义函数给每个交叉表添加变量名标题,提升表格可读性
  4. 扩展连续变量统计:如果需要加入连续变量的中位数(百分位数)和Wilcoxon检验结果,可生成对应表格后一起堆叠,示例:
# 生成连续变量统计表格(以review为例)
continuous_tbl <- tbl_summary(df, 
                              by = member,
                              include = review,
                              statistic = all_continuous() ~ "{median} ({p25}, {p75})",
                              missing = "no") |>
  add_p(test = all_continuous() ~ "wilcox.test") |>
  modify_header(all_cols() ~ "**{col}**")

# 合并连续变量表格和交叉表
tbl_stack(c(list(continuous_tbl), v))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:13:26