使用tbl_hierarchical结合tbl_merge时百分比全部为100%的问题咨询
tbl_hierarchical结合tbl_merge时百分比全部为100%的问题咨询
我来帮你分析一下问题所在,以及怎么修复这个百分比全为100%的异常情况~
问题根源
你的代码核心逻辑和tbl_hierarchical的参数设置不匹配,导致百分比计算出错:
- 你把
SAFFL/ITTFL等变量处理成仅保留Y和NA,然后试图通过by = .data[[var]]按这些变量分组,但同时将denominator设为全量的adsl数据集,这就打乱了百分比的计算逻辑。 - 你的核心需求应该是分别展示每个flag(SAFFL/ITTFL等)为
Y的人群中,SITEGR1和SITEID的分层分布,百分比基于该flag的总人数,但当前代码的分组和分母设置完全偏离了这个需求。
修复方案
我们需要调整lapply循环中tbl_hierarchical的调用逻辑,针对每个flag变量先筛选出目标人群,再生成对应的分层表格:
library(cards) library(gtsummary) library(dplyr) library(magrittr) # 数据预处理(和你的代码保持一致) adsl <- cards::ADSL %>% dplyr::mutate( SAFFL = dplyr::if_else(SAFFL == "Y", "Y", NA_character_), ITTFL = dplyr::if_else(ITTFL == "Y", "Y", NA_character_), EFFFL = dplyr::if_else(EFFFL == "Y", "Y", NA_character_), COMP8FL = dplyr::if_else(COMP8FL == "Y", "Y", NA_character_) ) group_vars <- c("SAFFL", "ITTFL", "EFFFL", "COMP8FL") # 调整循环逻辑:针对每个flag,先筛选出Y的子集再生成表格 tbl_list <- lapply(group_vars, function(var) { # 筛选当前flag为Y的目标人群 target_data <- adsl %>% filter(.data[[var]] == "Y") gtsummary::tbl_hierarchical( data = target_data, denominator = target_data, # 分母用当前flag的Y人群总数 id = USUBJID, variables = c(SITEGR1, SITEID) ) }) # 表格合并与格式调整(和你的代码逻辑一致) tbl <- gtsummary::tbl_merge(tbls = tbl_list) |> gtsummary::modify_spanning_header(dplyr::everything() ~ NA_character_) |> gtsummary::modify_header( stat_1_1 = "**SAFFL** \n(N = {n})", stat_1_2 = "**ITTFL** \n(N = {n})", stat_1_3 = "**EFFFL** \n(N = {n})", stat_1_4 = "**COMP8FL** \n(N = {n})" ) |> remove_footnote_header(columns = everything()) tbl
修复逻辑说明
- 精准筛选目标人群:针对每个flag变量,先过滤出该flag为
Y的观测作为分析数据集,确保我们只处理需要展示的人群。 - 正确设置分母:将
denominator设为同一个筛选后的子集,这样百分比的计算就会基于该flag的总人数(即表头N = {n}中的数值),而不是全量数据。 - 简化分组逻辑:去掉不必要的
by参数,让tbl_hierarchical直接输出目标人群的分层分布,保证每个子表格结构一致,合并后能得到符合预期的对比表格。
如果后续你需要对比flag的NA组,只需要调整筛选逻辑和by参数的使用即可,当前方案完全贴合你通过modify_header设置的展示需求。
内容来源于stack exchange
相关产品推荐
相关产品推荐

