在R函数中为多列添加百分比列及组间差值列的实现求助
问题解决:为分组统计结果添加百分比与差值列
问题场景
有一份带权重的调查数据集,已按处理组(mhst=1)和对照组(mhst=0)完成多列加权计数统计,需要为每组添加百分比列,以及计算两组百分比的差值列(对照组百分比 - 处理组百分比),但尝试的代码报错。
错误原因分析
- 过早转换为字符型:原代码在
adorn_totals()后立刻将所有列转为字符型,导致后续数值计算(百分比、差值)无法进行,这是核心错误。 - 百分比计算逻辑错误:用
mycol/sum(mycol)是错误写法,mycol是列名字符串而非实际数值列,且未按组计算各选项占该组总数的比例。 - 差值列写法错误:直接用
"0" - "1"是字符串相减,未正确引用对应列的数值,且列类型为字符时无法执行算术运算。
修改后的完整代码
library(tidyverse) library(janitor) df <- data.frame(mhst = factor(c(0,1,1,0)), q1 = factor(c(1, 4, 2, 2)), q2 = factor(c(3, 4, 5, 1)), q3 = factor(c(1, 4, 2, 5)), q4 = factor(c(2, 1, 1, 3)), WT1 = c(0.5, 0.3, 6, 1)) q_set_t1 <- c("q1", "q2", "q3", "q4") # 要统计的目标列 wt1 <- c("WT1") # 权重列 make_output <- function(mycol, weight) { output <- df %>% group_by_at(c("mhst", mycol)) %>% summarise_at(weight, sum) %>% rename(Q_set = all_of(mycol), weighted_count = all_of(weight)) %>% # 规范重命名 # 按组计算百分比(宽表转换前处理更简便) group_by(mhst) %>% mutate(percent = weighted_count / sum(weighted_count) * 100) %>% ungroup() %>% # 转宽表,同时保留计数和百分比,列名带上组标识 pivot_wider( names_from = mhst, values_from = c(weighted_count, percent), names_glue = "{mhst}_{.value}" ) %>% # 计算两组百分比差值 mutate(percent_diff = `0_percent` - `1_percent`) %>% # 添加总计行,自动处理数值列求和 janitor::adorn_totals("row") %>% # 数值保留两位小数后,再转字符型 mutate(across(where(is.numeric), ~round(., 2))) %>% mutate_all(~as.character(.)) # 添加变量名行和分隔空行 output <- bind_rows( tibble(var_name = mycol), output, tibble(var_name = "") ) return(output) } # 生成所有列的统计结果并合并 cols_output <- pmap(list(q_set_t1, wt1), make_output) q_set_wt <- bind_rows(cols_output) # 查看完整结果 print(q_set_wt, n = Inf)
关键修改说明
- 调整执行顺序:将数值计算(百分比、差值)放在字符转换前,确保计算时列保持数值类型。
- 规范列操作:用
all_of()处理列名字符串,用`0_percent`引用带特殊字符的列名,避免语法错误。 - 优化百分比逻辑:按
mhst分组计算各选项占组内总权重的比例,结果更贴合统计需求。 - 差值列实现:直接引用转换后的百分比列完成计算,同时保留两位小数提升可读性。
内容的提问来源于stack exchange,提问作者Ellie
相关产品推荐
相关产品推荐

