R语言调用ecdf与quantile计算分位数结果无差异原因
结果一致的原因
你遇到两组输出完全相同的问题,本质是对ecdf()和quantile()的组合计算逻辑理解错了,绝大多数情况都是以下原因导致:
- 核心逻辑问题:你当前的写法是拿单组数据自己算出的分位值,再喂给这组数据自己的ecdf函数,这种写法不管ff、gg两个向量的分布差得有多远,返回结果都会和你输入的
quants概率序列几乎完全重合,自然看起来两组输出一模一样。
原理非常直白:ecdf的返回值是「样本里小于等于输入值的观测占总样本数的比例」,当你用quantile(某组数据, 概率p)算出这组数据对应p位置的分位值v_p,再把v_p传给这组数据的ecdf,得到的结果本来就等于p,最多因为quantile内置的9种插值算法产生点可以忽略的数值误差,肉眼根本看不出差别。
你可以跑下面的测试代码立刻验证:set.seed(123) # 构造两个分布完全不搭边的向量 ff <- rnorm(1000, mean = 0, sd = 1) gg <- runif(1000, min = 10, max = 20) quants <- seq(0, 1, 0.2) # 跑你现在用的计算逻辑 res_ff <- ecdf(ff)(quantile(ff, quants)) res_gg <- ecdf(gg)(quantile(gg, quants)) # 打印出来就会发现,两个结果都和quants序列几乎一致,当然完全相同 print(res_ff) print(res_gg) - 参考方案的使用偏差:你参考的那段分组计算代码里,
quants是跨所有组统一的固定数值切点,不是每个组拿自己的dist列单独算出来的分位值。原方案的逻辑是拿一把统一的尺子,量每个组在这些固定数值点上的累积概率,不同组的结果自然有差异;你现在相当于每组自己造一把和自己适配的尺子量自己,量出来的比例当然全对齐。 - 极低概率特殊情况:如果你用的
quants本身是固定数值、不是0-1之间的概率序列,那只有当ff、gg两组数据在这些数值点上的累积占比刚好完全一致时,输出才会相同,这种情况在真实数据里基本碰不到。
修正方法
要实现原参考方案里的分组ecdf排名效果,得先拿全量数据算出统一的分位数值切点,再分组计算累积概率:
# 先用全量dist列算统一的分位数值切点 global_cutoff <- quantile(dat$dist, probs = quants) # 分组时传入全局统一的切点计算,这时候不同组的结果就会有差异 dat[, .(quant = global_cutoff, val = ecdf(dist)(global_cutoff)), by = rowval]
内容的提问来源于stack exchange,提问作者Tpellirn
相关产品推荐
相关产品推荐

