回首向来萧瑟处!
最近将这半年学习的编程内容进行了整理,以飨读者,如有错误,烦请不吝指正。
Table 14-1.01: 人口学基线特征汇总表
# =============================================================================# 文件名: 01_table_14-1.01.R# 用途: 生成 Table 14-1.01 人口学及基线特征汇总表# 输入: ADaM ADSL# 输出: RTF 格式表格# =============================================================================source(here("02_programs/tfl/00_tfl_setup.R"))adsl <- read_xpt(here("03_output/adam/adsl.xpt"))# --- 方法一: 使用 rtables 包 (FDA 推荐) ---library(rtables)# 定义分析函数count_fraction <- function(x) { in_rows( "n (%)" = c( sum(x == "Y", na.rm = TRUE), sum(x == "Y", na.rm = TRUE) / length(x[!is.na(x)]) * 100 ), format = "xx (xx.x)" )}# 构建表格tbl <- basic_table() %>% # 列分割: 按治疗组 split_cols_by("TRT01P") %>% add_colcounts() %>% # 总计数列 append_topleft("Table 14-1.01") %>% append_topleft("Summary of Demographics and Baseline Characteristics") %>% append_topleft("Safety Analysis Set") %>% append_topleft("") %>% # 年龄 (连续变量) split_rows_by("AGEGR1", label_pos = "topleft") %>% analyze("AGE", afun = list_wrap_x(summary), format = "xx.xx", stat_names = c("Mean", "SD", "Median", "Min", "Max")) %>% # 性别 (分类变量) split_rows_by("SEX", label_pos = "topleft") %>% analyze("SEX", afun = count_fraction) %>% # 种族 split_rows_by("RACE", label_pos = "topleft") %>% analyze("RACE", afun = count_fraction) %>% # 年龄组 split_rows_by("AGEGR1", label_pos = "topleft") %>% analyze("AGEGR1", afun = count_fraction) %>% # 国家 split_rows_by("COUNTRY", label_pos = "topleft") %>% analyze("COUNTRY", afun = count_fraction)# 过滤安全性分析集adsl_safety <- adsl %>% filter(SAFFL == "Y")# 生成表格result <- build_table(tbl, df = adsl_safety)# --- 输出为 RTF ---library(r2rtf)rtf_path <- here("03_output/tfls/tables/table_14-1.01.rtf")result %>% rtf_encode() %>% writeLines(rtf_path)message(sprintf("Table 14-1.01 已输出: %s", rtf_path))# --- 方法二: 使用 flextable (备选, 更灵活) ---library(flextable)summary_tbl <- adsl_safety %>% group_by(TRT01P) %>% summarise( N = n(), Age_Mean = mean(AGE, na.rm = TRUE), Age_SD = sd(AGE, na.rm = TRUE), Age_Median = median(AGE, na.rm = TRUE), Male_n = sum(SEX == "M", na.rm = TRUE), Male_pct = round(Male_n / N * 100, 1), Female_n = sum(SEX == "F", na.rm = TRUE), Female_pct = round(Female_n / N * 100, 1), .groups = "drop" )ft <- flextable(summary_tbl) %>% set_header_labels( TRT01P = "Treatment Group", N = "N", Age_Mean = "Age (Years)\nMean", Age_SD = "SD", Age_Median = "Median", Male_n = "Male\nn", Male_pct = "(%)", Female_n = "Female\nn", Female_pct = "(%)" ) %>% add_header_lines(c( "Table 14-1.01", "Summary of Demographics and Baseline Characteristics", "Safety Analysis Set" )) %>% theme_box() %>% autofit()save_as_docx(ft, path = here("03_output/tfls/tables/table_14-1.01.docx"))
夜雨聆风