如何在R中使用tbl_summary同时获取列百分比与行百分比?
用tbl_summary同时展示列百分比与行百分比
要实现分类变量单元格同时显示列百分比(n/分组总n)和行百分比(n/类别总n),且保留Overall列仅显示列百分比,可以通过modify_table_body自定义计算行百分比并修改统计文本,具体步骤如下:
完整代码实现
library(gtsummary) library(dplyr) library(stringr) # 1. 生成基础表格(默认列百分比,添加Overall列) iris_table_base <- iris %>% mutate(Sepal.Length.Cat = if_else(Sepal.Length > 5, "Big","Small")) %>% tbl_summary( by = Species, include = c(Sepal.Length.Cat, Sepal.Width), type = list(Sepal.Width ~ "continuous2"), statistic = list( all_continuous2() ~ c("{mean} ({sd})","{min} - {max}"), all_categorical() ~ "{n} ({p}%)" ), missing_text = "Missing" ) %>% add_overall(col_label = "**Overall** <br>N = {n}") %>% modify_footnote(update = everything() ~ NA) # 2. 计算每个分类类别的行总计(用于行百分比计算) row_totals <- iris_table_base$meta_data %>% filter(type == "categorical") %>% pull(variable) %>% purrr::map_dfr(function(var) { iris %>% select(all_of(var)) %>% count(!!sym(var), name = "row_n") }) # 3. 修改表格体,添加行百分比 iris_table_final <- iris_table_base %>% modify_table_body( ~ .x %>% left_join(row_totals, by = c("variable", "label")) %>% mutate( stat_display = case_when( # 仅对非Overall列的分类变量添加行百分比 !is.na(by) & type == "categorical" ~ str_replace( stat_display, "\\((\\d+\\.?\\d*)%\\)", paste0("(\\1%; ", round(n/row_n*100, 1), "%)") ), # 其他情况(连续变量、Overall列)保持原显示 TRUE ~ stat_display ) ) %>% select(-row_n) ) print(iris_table_final)
代码说明
- 基础表格构建:和你提供的代码一致,默认使用列百分比,添加Overall汇总列并移除脚注。
- 行总计计算:从表格元数据中筛选分类变量,计算每个类别(如Big、Small)的总样本数,为行百分比计算提供分母。
- 表格内容修改:
- 通过
left_join将行总计合并到表格数据中 - 用
case_when指定修改规则:仅对分组列(非Overall)的分类变量,替换原百分比文本,追加行百分比 - 连续变量和Overall列保持原有格式不变
- 通过
效果示例
- Setosa分组的Big类别会显示为
22 (44.0%; 18.6%),其中44.0%是列百分比(22/Setosa总样本50),18.6%是行百分比(22/Big总样本118) - Overall列的Big类别仍显示为
118 (78.7%),仅保留列百分比(118/总样本150)
内容的提问来源于stack exchange,提问作者Robyn Husa
相关产品推荐
相关产品推荐

