在R中如何让table1按列总数值而非行数计算分组百分比
方案1:基于table1包最小改动实现
你遇到的问题核心是table1默认按行数统计占比,只需新增weights参数指定权重为count列,即可自动按count列的实际统计值计算总和与对应占比,默认输出格式即为「人数总和(占比%)」,无需额外自定义渲染函数,修改后代码如下:
set.seed(123) dat <- data.frame( site = factor(sample(c("A", "B", "C", "D"), 100, replace = TRUE)), count = (sample(1:150, 100, replace = TRUE)), first.name = factor(sample(c("John", "Sue", "Bob", "Mary", "Cara"), 100, replace = TRUE)), last.name = factor(sample(c("Williams", "Smith", "Lee"), 100, replace = TRUE))) library(table1) tab <- table1(~ last.name + first.name | site, data = dat, weights = count, # 核心参数:指定count为权重,按实际统计值计算 digits= 1) tab
如果需要自定义数值格式、调整显示逻辑,也可以自行编写render.categorical函数实现。
方案2:基于dplyr+flextable自定义实现(更灵活)
如果需要更自由的表格格式调整,比如合并单元格、添加统计标识、自定义表头样式等,可以先手动汇总统计结果,再输出为规范统计表,代码如下:
library(dplyr) library(flextable) # 汇总姓氏分站点统计结果 last_res <- dat %>% group_by(site, last.name) %>% summarise(total = sum(count), .groups = "drop_last") %>% mutate(pct = round(100 * total / sum(total), 1), display = paste0(total, " (", pct, "%)")) %>% select(-total, -pct) %>% tidyr::pivot_wider(names_from = site, values_from = display) %>% rename("分类项" = last.name) %>% mutate(分类项 = paste0("姓氏:", 分类项)) # 汇总名字分站点统计结果 first_res <- dat %>% group_by(site, first.name) %>% summarise(total = sum(count), .groups = "drop_last") %>% mutate(pct = round(100 * total / sum(total), 1), display = paste0(total, " (", pct, "%)")) %>% select(-total, -pct) %>% tidyr::pivot_wider(names_from = site, values_from = display) %>% rename("分类项" = first.name) %>% mutate(分类项 = paste0("名字:", 分类项)) # 合并结果输出三线表格式的规范统计表 final_tab <- bind_rows(last_res, first_res) %>% flextable() %>% theme_booktabs() %>% autofit() final_tab
内容的提问来源于stack exchange,提问作者SageandSun
相关产品推荐
相关产品推荐

