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

如何用R语言独立汇总多列分类变量的计数与占比

问题

需要对如下示例表格中的eth_source_1、eth_source_2、eth_source_3三列分类变量,分别独立计算各类别的计数和占比并汇总展示。尝试用group_by(eth_source_1, eth_source_2, eth_source_3)同时分组,得到的是所有组合的交叉矩阵,并非各列独立的统计结果;目前通过分别生成各列汇总表再合并的方式实现,但想找到更简洁的方法。

示例数据:

patient_ideth_source_1eth_source_2eth_source_3
1WhiteN/AWhite
2South AsianSouth_AsianSouth_Asian
3MixedMixedN/A

现有实现代码:

summary_a <- patient_ethn %>%
  group_by(eth = eth_source_1) %>%
  summarise(n_1 = n()) %>%
  mutate (freq_1 = formattable::percent (n_1/sum(n_1)))

summary_b <- patient_ethn %>%
  group_by(eth = eth_source_2) %>%
  summarise(n_2 = n()) %>%
  mutate (freq_2 = formattable::percent (n_2/sum(n_2)))

summary_c <- patient_ethn %>%
  group_by(eth = eth_source_3) %>%
  summarise(n_3 = n()) %>%
  mutate (freq_3 = formattable::percent (n_3/sum(n_3)))

patient_summary <- full_join(summary_a, summary_b, by='eth')
full_join(patient_summary, summary_c, by='eth')

期望输出:

# A tibble: 6 × 7
  eth                      n_1   freq_1       n_2   freq_2       n_3   freq_3
  <chr>                    <int> <formttbl>   <int> <formttbl>   <int> <formttbl>
1 White                     #### #.##%         #### #.##%         #### #.##%         
2 South Asian               #### #.##%         #### #.##%         #### #.##%     
3 Mixed                     #### #.##%         #### #.##%         #### #.##%   
4 NA                        #### #.##%         #### #.##%         #### #.##%  

简洁实现方法

可以通过数据重塑+统一统计+再重塑的流程简化代码,避免重复编写分组逻辑:

library(tidyverse)
library(formattable)

patient_summary <- patient_ethn %>%
  # 宽表转长表:将3个种族列合并为source(原列标识)和eth(种族值)两列
  pivot_longer(cols = starts_with("eth_source"), 
               names_to = "source", 
               values_to = "eth") %>%
  # 按数据源和种族分组,统一计算计数和占比
  group_by(source, eth) %>%
  summarise(n = n(), 
            freq = percent(n / sum(n)), 
            .groups = "drop") %>%
  # 长表转宽表:将统计结果拆分为对应原列的计数、占比列
  pivot_wider(names_from = source, 
              values_from = c(n, freq), 
              names_glue = "{str_remove(source, 'eth_source_')}_{.value}") %>%
  # 调整列顺序,匹配期望输出结构
  select(eth, n_1, freq_1, n_2, freq_2, n_3, freq_3)

代码说明

  • 转长表:用pivot_longer把多列种族数据统一格式,后续只需写一次统计逻辑,不用重复分组。
  • 统一统计:按数据源和种族分组,一次计算所有组的计数和占比,.groups = "drop"清理分组状态避免干扰后续操作。
  • 转宽表:用names_glue生成n_1、freq_1这类和原代码一致的列名,直接得到宽表格式的汇总结果。
  • 调整列序:通过select把列排列成期望的顺序。

这种方法扩展性更强,后续新增eth_source_*列时,只需修改pivot_longer的cols参数即可,无需重复编写分组汇总代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:51:02