R语言如何在data.frame中按指定变量对二元结局进行分组制表
R 中按多维度聚合二元结局计数的实现方法
核心逻辑
你需要实现的本质,是把相同id、相同月份下的重复记录做折叠,按固定维度(id、month、gender、type)分组,统计每个分组内二元变量outcome取1、取0的记录数,最终将两个计数值展开为独立的outcome1、outcome0列。
实现方案
方案1:dplyr 链式聚合(可读性最优)
这是日常数据处理中最常用的方案,逻辑清晰易维护:
# 提前安装并加载dplyr包(首次使用运行 install.packages("dplyr")) library(dplyr) result <- data1 %>% # 按所有需要保留的非计数字段分组 group_by(id, month, gender, type) %>% # 分别统计每个组内outcome=1、outcome=0的记录数 summarise( outcome1 = sum(outcome == 1, na.rm = TRUE), outcome0 = sum(outcome == 0, na.rm = TRUE), .groups = "drop" ) %>% # 调整列顺序完全匹配目标输出结构 select(id, outcome1, outcome0, month, gender, type)
运行上述代码得到的结果与你列出的期望输出完全一致,na.rm = TRUE参数可自动跳过组内缺失的outcome记录,避免计数被缺失值干扰。
方案2:base R 原生实现(无第三方依赖)
如果不想额外安装包,可以直接用R自带的aggregate函数完成聚合:
# 定义组内计数逻辑 count_outcome <- function(x) { c( outcome1 = sum(x == 1), outcome0 = sum(x == 0) ) } # 按维度聚合 result_base <- aggregate( outcome ~ id + month + gender + type, data = data1, FUN = count_outcome ) # 拆分聚合返回的结果矩阵,整理为目标结构 result_base <- cbind( result_base[, c("id", "month", "gender", "type")], result_base$outcome )
方案3:长转宽思路(扩展性更强)
如果后续outcome的取值维度变多(比如新增取值2、3),可以搭配tidyr的宽表转换逻辑实现自动生成计数列,无需手动写统计规则:
library(tidyr) result_wide <- data1 %>% # 先按所有维度+outcome值统计频次 count(id, month, gender, type, outcome) %>% # 将outcome取值转为独立列,缺失的计数自动填充为0 pivot_wider( names_from = outcome, names_prefix = "outcome", values_from = n, values_fill = 0 ) %>% select(id, outcome1, outcome0, month, gender, type)
注意事项
分组时需要把所有不随组内记录变化的字段(本数据中同一id对应的gender、type是固定值)都纳入分组变量,否则聚合时会将这些字段过滤掉,无法得到带完整字段的结果表。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

