定制tern/R包:按SOC-PT分组统计AE并展示患者占比
解决方案
要实现“发生该AE的患者数/组内总患者数”的展示形式,需要从统计逻辑自定义和列标签调整两部分入手,具体实现如下:
1. 核心思路
- 替换默认的
count_occurrences函数,改用自定义统计逻辑计算每组内发生特定AE的患者数,同时关联adsl中的组总患者数,拼接成n/N格式 - 移除默认的
show_colcounts,直接将组总患者数嵌入列标题,明确分母含义
2. 完整实现代码
library(pharmaverseadam) library(tern) library(dplyr) adsl <- adsl %>% df_explicit_na() adae <- adae %>% df_explicit_na() %>% var_relabel( AEBODSYS = "MedDRA System Organ Class", AEDECOD = "MedDRA Preferred Term" ) %>% filter(SAFFL == "Y") # 提前计算各组总患者数,用于列标签和统计分母 get_group_totals <- function(df) { df %>% group_by(ACTARM) %>% summarise(N = n_distinct(USUBJID)) %>% bind_rows(tibble(ACTARM = "All Patients", N = n_distinct(df$USUBJID))) } group_totals <- get_group_totals(adsl) arm_labels <- paste0(group_totals$ACTARM[1:nlevels(adsl$ACTARM)], " (N=", group_totals$N[1:nlevels(adsl$ACTARM)], ")") overall_label <- paste0("All Patients (N=", group_totals$N[nrow(group_totals)], ")") # 自定义统计函数:输出"发生AE患者数/组总患者数"格式 stat_ae_n_over_N <- function(x, .N) { n <- length(unique(x)) list(ratio = paste0(n, "/", .N)) } split_fun <- drop_split_levels lyt <- basic_table() %>% # 替换列标签为带总患者数的格式 split_cols_by(var = "ACTARM", labels = arm_labels) %>% add_overall_col(label = overall_label) %>% # 顶部AE汇总统计改为n/N格式 analyze_num_patients( vars = "USUBJID", .stats = "unique", .labels = c(unique = "Total patients with at least one adverse event"), .formats = c(unique = function(x, .N) paste0(x, "/", .N)), .extra_args = list(.N = group_totals$N) ) %>% split_rows_by( "AEBODSYS", child_labels = "visible", nested = FALSE, split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adae$AEBODSYS) ) %>% # SOC层级统计改为n/N格式 summarize_num_patients( var = "USUBJID", .stats = "unique", .labels = c(unique = "Total patients with at least one adverse event"), .formats = c(unique = function(x, .N) paste0(x, "/", .N)), .extra_args = list(.N = group_totals$N) ) %>% # 替换count_occurrences,用自定义函数实现PT层级的n/N展示 analyze_vars( vars = "AEDECOD", var_labels = obj_label(adae$AEDECOD), .stats = "ratio", .labels = c(ratio = ""), .indent_mods = 1L, .fun = stat_ae_n_over_N, .extra_args = list(.N = group_totals$N) ) result <- build_table(lyt, df = adae, alt_counts_df = adsl) result
3. 关键修改说明
- 列标签优化:通过
get_group_totals从adsl提取每组总患者数,直接将(N=xxx)嵌入列标题,替代默认的列计数展示 - 统计逻辑统一:从顶部汇总、SOC层级到PT层级,全部使用自定义函数输出
n/N格式,确保表格逻辑一致 - 参数传递:通过
.extra_args将组总患者数传递给统计函数,保证分母是每组的全部患者数,而非仅发生AE的患者数
内容的提问来源于stack exchange,提问作者Viburnum
相关产品推荐
相关产品推荐

