如何在group_by语句中运用函数实现分组统计与百分位计算?
解决方案
核心思路
针对每个分组变量单独处理:先按分组计算实际值的均值,再基于该组内所有观测的模拟值计算每轮模拟的组内均值,最后用经验分布函数(ECDF)得到实际均值在模拟均值序列中的百分位,最终合并两个分组的结果。
完整代码
library(dplyr) library(purrr) # 初始化示例数据(和你提供的一致) set.seed(123) # 设置随机种子保证结果可复现 df <- data.frame(group_var1 = c(rep("A", 5), rep("B", 5)), group_var2 = c(rep(c("C", "D"), 5)), value = runif(10)) df <- df %>% mutate(simulations = list(runif(100))) # 定义处理单个分组变量的函数 process_group <- function(df, group_col) { df %>% group_by(!!sym(group_col)) %>% summarize( mean_value = mean(value), # 提取组内所有模拟列表,转成矩阵后按列取均值(每轮模拟的组内平均) sim_group_avg = list(rowMeans(simplify2array(simulations))) ) %>% ungroup() %>% # 计算实际均值在组内模拟均值序列中的百分位 mutate( simulation_percentile = map_dbl(sim_group_avg, ~ecdf(.x)(mean_value)), risk_factor = group_col, risk_class = as.character(!!sym(group_col)) ) %>% select(risk_factor, risk_class, mean_value, simulation_percentile) } # 处理两个分组变量并合并结果 final_result <- bind_rows( process_group(df, "group_var1"), process_group(df, "group_var2") ) # 查看结果 print(final_result)
关键细节说明
- 编程式分组:用
!!sym(group_col)将字符串形式的分组变量名转换为可用于group_by的符号,实现对任意分组变量的通用处理。 - 组内模拟均值计算:每个分组内的
simulations是多个长度为100的列表,用simplify2array转成行数等于观测数、列数等于模拟轮数的矩阵,再用rowMeans得到每一轮模拟的组内均值。 - 百分位计算:对每个分组的模拟均值序列单独构建ECDF,避免全局模拟结果干扰分组的百分位计算,确保结果是组内的相对位置。
内容的提问来源于stack exchange,提问作者Tor97
相关产品推荐
相关产品推荐

