基于累积分布表计算四分位数及均值的R技术问询
基于累积分布(cdf)计算分位数与均值的解决方案
核心思路
你的数据是预汇总的频率分布表,而非原始个体数据,因此不能直接用quantile()(它默认对原始数据排序计算)。需要基于cdf列(累积概率)匹配对应的分位数点,同时均值可通过加权求和直接计算。
1. 计算四分位数(两种常用方法)
假设你的原始数据结构包含group、size、prop、cdf列,以下是两种实现方式:
方法1:阶梯式分位数(取第一个满足cdf≥分位数概率的size)
这种方法适用于离散型累积分布,直接取累积概率首次达到目标分位数对应的size:
library(dplyr) data %>% group_by(group) %>% summarize( Q1 = size[which(cdf >= 0.25)[1]], median = size[which(cdf >= 0.5)[1]], Q3 = size[which(cdf >= 0.75)[1]], .groups = "drop" ) %>% mutate(across(where(is.numeric), round, 0))
方法2:线性插值分位数(更精确的连续型估计)
如果需要更平滑的分位数估计,可对cdf和size做线性插值,找到对应分位数概率的size值:
library(dplyr) library(purrr) # 定义单个分组的分位数计算函数 calc_quantiles <- function(cdf_vec, size_vec, probs = c(0.25, 0.5, 0.75)) { approx(x = cdf_vec, y = size_vec, xout = probs)$y } data %>% group_by(group) %>% summarize( # 先按cdf排序,确保累积顺序正确 cdf = sort(cdf), size = size[order(cdf)], # 计算分位数 quantiles = list(calc_quantiles(cdf, size)), # 计算均值 mean_val = sum(size * prop), .groups = "drop" ) %>% unnest_wider(quantiles, names_sep = "_") %>% rename(Q1 = quantiles_1, median = quantiles_2, Q3 = quantiles_3) %>% mutate(across(c(Q1, median, Q3, mean_val), round, 0))
2. 计算均值
均值是size与对应概率prop的加权和(因为prop是每个size的概率,直接求和即可,无需除以n):
data %>% group_by(group) %>% summarize(mean_val = sum(size * prop), .groups = "drop") %>% mutate(mean_val = round(mean_val, 0))
针对你更新的数据示例说明
如果你的数据已经按cut_cdf(四分位区间)分组,每个区间对应的size可直接作为该分位数区间的代表值,此时四分位数可直接映射:
data %>% group_by(group) %>% summarize( Q1 = size[cut_cdf == "(0,0.25]"], median = size[cut_cdf == "(0.25,0.5]"], Q3 = size[cut_cdf == "(0.75,1]"], .groups = "drop" ) %>% mutate(across(where(is.numeric), round, 0))
内容的提问来源于stack exchange,提问作者newstudenttoprogramming
相关产品推荐
相关产品推荐

