如何用一段R代码计算多条件下的汇总统计量?
整合多层级统计量的R实现
问题描述
现有如下数据框:
df <- data.frame(yr = c("2008", "2008", "2008", "2008", "2008", "2009", "2009"), FM = c(1, 1, 1, 1, 0, 1, 0), t1 = c(0, 1, 0, 1, 0, 1, 0), t2 = c(0, 0, 1, 1, 0, 0, 1))
需要一次性获取三类汇总统计量:
- 按年份统计FM=1和FM=0的个体数量及占比
- 在FM=1的条件下,统计t1=1和t1=0的个体数量及占比
- 在FM=1且t1=1的条件下,统计t2=1和t2=0的个体数量及占比
原分步代码需三次独立处理数据,现需合并为一段代码以提升简洁性和大数据集性能。
解决方案
可以通过单次分组+批量计算的方式,在一次数据遍历中完成所有统计,再按需整理格式:
library(dplyr) library(tidyr) # 核心计算:一次分组完成所有统计 result <- df %>% group_by(yr) %>% summarise( # 第一层级:FM的数量与占比(按年份整体) count_FM0 = sum(FM == 0), perc_FM0 = count_FM0 / n(), count_FM1 = sum(FM == 1), perc_FM1 = count_FM1 / n(), # 第二层级:FM=1时t1的数量与占比(基于FM=1的子集) count_t1_FM1_0 = sum(FM == 1 & t1 == 0), perc_t1_FM1_0 = ifelse(count_FM1 == 0, NA, count_t1_FM1_0 / count_FM1), count_t1_FM1_1 = sum(FM == 1 & t1 == 1), perc_t1_FM1_1 = ifelse(count_FM1 == 0, NA, count_t1_FM1_1 / count_FM1), # 第三层级:FM=1且t1=1时t2的数量与占比(基于FM=1&t1=1的子集) count_t2_FM1t11_0 = sum(FM == 1 & t1 == 1 & t2 == 0), perc_t2_FM1t11_0 = ifelse(count_t1_FM1_1 == 0, NA, count_t2_FM1t11_0 / count_t1_FM1_1), count_t2_FM1t11_1 = sum(FM == 1 & t1 == 1 & t2 == 1), perc_t2_FM1t11_1 = ifelse(count_t1_FM1_1 == 0, NA, count_t2_FM1t11_1 / count_t1_FM1_1), .groups = "drop" # 取消分组,返回普通数据框 ) # 可选:转换为长格式,更易阅读 result_long <- result %>% pivot_longer( cols = -yr, names_to = c("stat_type", "category"), names_sep = "_", values_to = "value" ) %>% pivot_wider( names_from = stat_type, values_from = value ) # 查看结果 print(result_long)
代码说明
- 单次分组:仅按
yr分组一次,避免多次过滤和分组操作,大幅提升大数据集的处理效率。 - 批量计算:通过
sum()直接统计各条件下的样本数,用除法计算占比,同时加入ifelse()避免分母为0的报错。 - 格式转换:利用
tidyr的pivot_longer()和pivot_wider()将宽格式结果转换为更易读的长格式,可根据需求选择保留宽/长格式。
运行后得到的长格式结果示例:
# A tibble: 6 × 4 yr category count perc <chr> <chr> <int> <dbl> 1 2008 FM0 1 0.2 2 2008 FM1 4 0.8 3 2008 t1_FM1_0 2 0.5 4 2008 t1_FM1_1 2 0.5 5 2008 t2_FM1t11_0 1 0.5 6 2008 t2_FM1t11_1 1 0.5 # ℹ 2 more rows
内容的提问来源于stack exchange,提问作者vog
相关产品推荐
相关产品推荐

