如何用gt/gtsummary按第二变量自动生成行组或表头?
长格式计数数据按分类变量生成行组的程序化实现(gt/gtsummary)
我需要对长格式计数数据,按照第二个分类变量进行汇总,希望用gt或gtsummary工具,程序化地基于主变量对应的分类变量插入行表头(用tab_row_group()生成行组),而非手动指定行号或匹配标签。
示例数据
library(gt) library(gtsummary) library(tidyverse) aes <- data.frame( preferred_term = c("Headache", "Fatigue", "Anxiety", "Anxiety", "Headache", "Contusion", "Depressed Mood", "Gait disturbance"), system_organ_class = c("Nervous System Disorders", "General disorders and administration site conditions", "Psychiatric disorders", "Psychiatric disorders", "Nervous System Disorders", "Skin and subcutaneous tissue disorders", "Psychiatric disorders", "General disorders and administration site conditions") )
一、手动用gt实现(非程序化)
该方法需要手动指定每个行组的标签和对应行号,数据变动时需手动调整,灵活性差:
left_join( aes %>% group_by(preferred_term) %>% summarize(n = n()) %>% mutate( p = round((n / sum(n)) * 100, 1), n_p = paste0(n, " (", p, ")") ), aes %>% distinct(), by = "preferred_term" ) %>% arrange(system_organ_class) %>% select(-c(n, p, system_organ_class)) %>% gt() %>% tab_row_group( label = "General disorders and administration site conditions", rows = 1:2 ) %>% tab_row_group( label = "Nervous System Disorders", rows = 3:3 ) %>% tab_row_group( label = "Psychiatric disorders", rows = 4:5 ) %>% tab_row_group( label = "Skin and subcutaneous tissue disorders", rows = 6:6 )
二、用gtsummary生成宽格式汇总(不符合需求)
tbl_summary(by = ...)会生成按分类变量分列的宽格式表格,不是行组形式,无法满足按分类变量分组展示行的需求:
aes %>% tbl_summary(by = system_organ_class)
三、手动用gtsummary+modify_table_body实现(非程序化)
通过case_when手动匹配术语和分类组,数据更新时需修改匹配规则,同样缺乏灵活性:
aes %>% tbl_summary( include = preferred_term ) %>% modify_table_body( mutate, groupname_col = case_when( label %in% c("Fatigue", "Gait disturbance") ~ "General disorders and administration site conditions", label == "Headache" ~ "Nervous System Disorders", label %in% c("Anxiety", "Depressed Mood") ~ "Psychiatric disorders", label == "Contusion" ~ "Skin and subcutaneous tissue disorders", TRUE ~ "" ) )
四、程序化解决方案
方案1:gtsummary实现(推荐)
先提取术语与分类组的映射关系,再通过left_join关联到汇总表中,自动生成行组,无需手动匹配:
aes %>% tbl_summary(include = preferred_term) %>% modify_table_body( ~ .x %>% # 关联术语对应的分类组 left_join( aes %>% distinct(preferred_term, system_organ_class), by = c("label" = "preferred_term") ) %>% # 将分类组设为行组列 rename(groupname_col = system_organ_class) %>% # 按分类组和术语排序 arrange(groupname_col, label) ) %>% # 优化表头显示 modify_header(label = "不良反应术语") %>% bold_labels()
方案2:gt实现
先整理汇总数据,再通过循环自动为每个分类组添加行组,无需手动指定行号:
# 第一步:汇总并整理数据,保留分类组信息 aes_summary <- aes %>% group_by(system_organ_class, preferred_term) %>% summarize(n = n(), .groups = "drop") %>% mutate( p = round(n / sum(n) * 100, 1), n_p = paste0(n, " (", p, ")") ) %>% arrange(system_organ_class, preferred_term) # 第二步:初始化gt表格 gt_table <- aes_summary %>% select(preferred_term, n_p) %>% gt() %>% cols_label(preferred_term = "不良反应术语", n_p = "例数(%)") # 第三步:循环添加行组 unique_soc <- unique(aes_summary$system_organ_class) for (soc in unique_soc) { # 获取当前分类组对应的所有术语 term_list <- filter(aes_summary, system_organ_class == soc)$preferred_term gt_table <- gt_table %>% tab_row_group(label = soc, rows = preferred_term %in% term_list) } gt_table
内容的提问来源于stack exchange,提问作者Raoul Duke
相关产品推荐
相关产品推荐

