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

gtsummary包tbl_custom_summary自定义百分比计算报错问题

自定义百分比分母的gtsummary表格报错解决

问题背景

需要生成分类变量的摘要表格,用固定值25作为百分比计算的分母(而非数据总样本量17)。此前代码运行正常,但更新dplyr、glue、gtsummary等包后出现报错,调试发现传入自定义统计函数的data为空,错误信息逻辑模糊。

示例代码

example_data <- tibble(term = c(rep("A", 4), rep("B", 6), rep("C", 7)))

custom_percent <- function(data, ...) {
  n <- nrow(data)
  pct <- paste0(round(100*n/25, 1), "%")
  dplyr::tibble(N = n, Percentage = pct)
}
                       
example_data %>% 
  tbl_custom_summary(stat_fns = everything() ~ custom_percent,
                     statistic = everything() ~ "{N} ({Percentage})")

报错信息

Error in `$<-`:
! Assigned data `*vtmp*` must be compatible with existing data.
✖ Existing data has 14 rows.
✖ Assigned data has 10 rows.
ℹ Only vectors of size 1 are recycled.
Caused by error in `vectbl_recycle_rhs_rows()`:
! Can't recycle input of size 10 to size 14.
Run `rlang::last_trace()` to see where the error occurred.
Warning message:
Unknown or uninitialised column: `fmt_fn`.

问题原因

  1. 新版本gtsummary参数要求变更:tbl_custom_summary的stat_fns参数现在要求自定义函数返回的tibble必须包含stat和fmt_fn列,原代码返回的N和Percentage列不符合结构要求,导致数据匹配错误。
  2. 空数据处理缺失:分组逻辑更新后,部分分组会传入空数据框,原函数未处理这种情况,引发后续行数不匹配问题。

解决方案

方案1:改用tbl_summary + add_stat(推荐,更稳定)

该组合更适配新版本gtsummary的自定义统计量逻辑,无需严格遵循tbl_custom_summary的返回结构:

library(gtsummary)
library(dplyr)

example_data <- tibble(term = c(rep("A", 4), rep("B", 6), rep("C", 7)))

custom_percent <- function(data, ...) {
  # 处理空数据情况
  if (nrow(data) == 0) {
    return(tibble(N = 0, Percentage = "0.0%"))
  }
  n <- nrow(data)
  pct <- paste0(round(100*n/25, 1), "%")
  tibble(N = n, Percentage = pct)
}

# 生成表格
example_data %>%
  tbl_summary(
    include = term,
    # 定义统计量显示格式
    statistic = list(all_categorical() ~ "{N} ({Percentage})")
  ) %>%
  # 添加自定义统计量
  add_stat(
    fns = all_categorical() ~ custom_percent
  )

方案2:调整tbl_custom_summary的自定义函数

如果坚持使用tbl_custom_summary,需修改函数返回符合要求的结构:

library(gtsummary)
library(dplyr)

example_data <- tibble(term = c(rep("A", 4), rep("B", 6), rep("C", 7)))

custom_percent <- function(data, ...) {
  if (nrow(data) == 0) {
    n <- 0
    pct_str <- "0.0%"
  } else {
    n <- nrow(data)
    pct_str <- paste0(round(100*n/25, 1), "%")
  }
  # 返回包含stat和fmt_fn的tibble
  tibble(
    stat = paste0(n, " (", pct_str, ")"),
    fmt_fn = function(x) x # 直接返回格式化后的字符串
  )
}

example_data %>% 
  tbl_custom_summary(
    stat_fns = everything() ~ custom_percent,
    statistic = everything() ~ "{stat}"
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 07:13:14