You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言dplyr按多列分组批量统计多列计数与占比

问题描述

现有全因子类型数据框df,包含gender、country2个分组字段,以及a、b、c、d4个待统计字段,数据构造代码如下:

set.seed(123)
gender <- sample(1:2,12,replace=T)
country <- c('FIN', 'FIN', 'EST', 'NIG','NIG','JAM', 'FIN', 'NIG', 'EST', 'NIG','NIG','JAM','FIN', 'FIN', 'EST', 'NIG','NIG','JAM', 'FIN', 'NIG', 'EST', 'NIG','NIG','JAM')
a <- sample(1:5,24,,replace=T)
b <- sample(1:5,24,,replace=T)
c <- sample(1:5,24,,replace=T)
d <- sample(1:5,24,,replace=T)
# 合并变量生成数据框
df <- data.frame(gender,country,a,b,c,d)
df <- df %>% mutate_at(c("gender","country","a","b","c","d"), as.factor)

需求为按gender、country分组,统计a到d所有列的组内占比百分比与对应样本量n,要求不重复编写同类代码,批量完成4个字段的统计。

目前单字段(a列)的统计逻辑已验证可行:先按gender、country、a分组计算各组样本量totaln,再按country、gender分组计算组内百分比percentage,代码如下:

df %>% 
  group_by(gender,country,a) %>%
  summarise(totaln=n()) %>% 
  group_by(country,gender) %>% 
  mutate(percentage=totaln/sum(totaln)*100) 

a列统计输出结果如下:

gender country a     totaln percentage
   <fct>  <fct>   <fct>  <int>      <dbl>
 1 1      EST     1          2       50  
 2 1      EST     3          1       25  
 3 1      EST     4          1       25  
 4 1      FIN     1          1       25  
 5 1      FIN     2          3       75  
 6 1      NIG     1          1       25  
 7 1      NIG     2          1       25  
 8 1      NIG     3          1       25  
 9 1      NIG     4          1       25  
10 2      FIN     1          1       50  
11 2      FIN     3          1       50  
12 2      JAM     1          2       50  
13 2      JAM     3          2       50  
14 2      NIG     3          1       16.7
15 2      NIG     4          1       16.7
16 2      NIG     5          4       66.7

实现方案

通过长表转换统一处理所有待统计字段,无需逐列重复编写统计代码,完整代码如下:

library(tidyverse)

df %>%
  pivot_longer(
    cols = a:d,
    names_to = "var_name",
    values_to = "var_level"
  ) %>%
  group_by(gender, country, var_name, var_level) %>%
  summarise(totaln = n(), .groups = "drop_last") %>%
  mutate(percentage = totaln / sum(totaln) * 100) %>%
  ungroup()

逻辑说明:

  • 用pivot_longer将a-d四个待统计字段从宽格式转为长格式:var_name列标记当前统计的字段名(a/b/c/d),var_level列存储对应字段的因子取值
  • 分组统计时将var_name、var_level加入分组规则,所有字段的计数、占比计算一次性完成
  • summarise中设置.groups = "drop_last"会自动移除最内层的var_level分组,刚好匹配后续按gender、country、var_name分组计算组内占比的需求,无需重复调用group_by调整分组层级

输出结果中var_name为a的部分和单跑a列的结果完全一致,b、c、d列的统计逻辑完全相同。如果需要宽表格式的结果,可在上述代码末尾追加pivot_wider逻辑按需转换。


内容的提问来源于stack exchange,提问作者user19250276

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:51:26