R语言如何批量对每列按自身分组计数并计算占比生成统一数据框
最优实现方案(tidyverse 生态)
使用purrr包的列遍历功能直接批量处理所有列,自动合并为统一结果数据框,无需手动维护循环逻辑:
library(tidyverse) # 示例数据 a<- rep(1:5, 5) b <- rep(1:5, 5) c <- rep(1:5, 5) d <- rep(1:5, 5) df <- data.frame(a=a, b=b, c=c, d=d) # 批量处理代码 all_col_result <- map_dfr(names(df), function(col_name) { df %>% group_by(across(all_of(col_name))) %>% summarise(count = n()) %>% pivot_wider(names_from = all_of(col_name), values_from = count) %>% mutate( sum = rowSums(across(where(is.numeric))), neg = (`1` + `2`)/sum, pos = (`4` + `5`)/sum, neut = `3`/sum ) %>% select(pos, neg, neut) %>% # 可选:新增字段标记当前结果对应的原始列名 mutate(source_col = col_name, .before = 1) }) # 输出结果 all_col_result
修正后的for循环实现
如果你更习惯用for循环,修改你的错误写法后可用版本如下:
# 初始化空结果容器 all_col_result <- data.frame() for (col_name in names(df)) { temp_res <- df %>% group_by(across(all_of(col_name))) %>% summarise(count = n()) %>% pivot_wider(names_from = all_of(col_name), values_from = count) %>% mutate( sum = rowSums(across(where(is.numeric))), neg = (`1` + `2`)/sum, pos = (`4` + `5`)/sum, neut = `3`/sum ) %>% select(pos, neg, neut) %>% mutate(source_col = col_name, .before = 1) # 拼接单例结果到总表 all_col_result <- rbind(all_col_result, temp_res) }
说明
- 原代码报错核心原因是
!!df[i,]用法错误,group_by需要传入列名而非列的取值,用across(all_of(列名字符串))可以实现动态指定分组列 - 用
rowSums(across(where(is.numeric)))替代硬编码的.[1:5],适配列取值个数变化的场景,兼容性更强
内容的提问来源于stack exchange,提问作者ArturR2
相关产品推荐
相关产品推荐

