R语言按两个变量分组聚合统计table数据的解决方案
代码报错核心原因
你之前的写法跑不通主要是两个问题:
- 写的for循环是逐行取
df1[i,1]也就是X1列的单个单元格值做聚合,完全搞错了聚合的输入对象,而且循环里没有赋值存储结果,就算能运行也不会返回你要的统计值 - 之前尝试
aggregate失败,大概率是没正确指定双分组规则,也没把所有需要统计的年份列都传入计算参数,你的数据是宽表结构,多列存不同年份的0/1标记,只传单列肯定出不了正确结果。
可直接运行的实现方案
不需要写for循环,R的分组统计函数原生支持按多变量分组批量计算多列指标,给你两个最常用的写法,选一个用就行。
方案1:基础R原生aggregate写法(不用装额外包)
先确认你数据框里的列名:你贴的示例里第二年的列名误标成了[x2 - year 2],先把列名修正,假设三个年份列的列名分别是year1、year2、year3(替换成你自己的真实列名即可),运行下面代码:
# 按X1(住院类型)、X2(专科)双分组,统计各年份医生数 doctor_count <- aggregate( x = df1[, c("year1", "year2", "year3")], # 传入所有需要求和的年份列 by = list(type_sejour = df1$X1, specialite = df1$X2), # 指定两个分组维度 FUN = sum, # 对0/1列求和,结果就是对应分组的医生数 na.rm = TRUE # 自动忽略缺失值 )
用你给的示例数据跑,得到的结果和手动计数完全一致:
- 骨科(ortho):第1年1人、第2年2人、第3年1人
- 外科(chir):第1年1人、第2年2人、第3年3人
方案2:tidyverse写法(语法更直观,适合后续数据处理)
如果后续要做更多数据清洗,可以用更易读的tidyverse语法:
# 第一次用先运行下面这行装包,装过就跳过 # install.packages("tidyverse") library(tidyverse) doctor_count <- df1 %>% group_by(X1, X2) %>% # 指定按X1、X2分组 summarise( across(matches("year"), ~sum(.x, na.rm = TRUE)), # 批量对所有年份列求和 .groups = "drop" # 计算完取消分组,避免后续操作出问题 )
注意事项
- 运行代码前一定要先核对列名,必须和你自己
df1里的真实列名完全一致,不要直接复制代码里的year1这类占位列名 - 你的原始数据每行对应1名医生,年份列取值0/1,对0/1求和的逻辑完全正确,结果就是对应分组、对应年份的医生总数,不需要额外做数据转换
- 这类分组聚合场景完全不需要手动写for循环,内置的分组函数已经做了优化,手动写循环不仅代码冗余,还很容易出现下标索引写错的问题。
内容的提问来源于stack exchange,提问作者user19304348
相关产品推荐
相关产品推荐

