可靠地检索分位数函数的倒数
Posted
技术标签:
【中文标题】可靠地检索分位数函数的倒数【英文标题】:Reliably retrieve the reverse of the quantile function 【发布时间】:2019-11-05 13:05:54 【问题描述】:我已阅读其他有关获取分位数“反向”的帖子(例如here) - 即获取与一系列值中的某个值相对应的百分位数。
但是,对于相同的数据系列,答案并没有给出与分位数相同的值。
我还研究了分位数提供了 9 种不同的算法来计算百分位数。
所以我的问题是:有没有可靠的方法来获得分位数函数的反转? ecdf 不接受“类型”参数,因此似乎无法确保它们使用相同的方法。
可重现的例子:
# Simple data
x = 0:10
pcntile = 0.5
# Get value corresponding to a percentile using quantile
(pcntile_value <- quantile(x, pcntile))
# 50%
# 5 # returns 5 as expected for 50% percentile
# Get percentile corresponding to a value using ecdf function
(pcntile_rev <- ecdf(x)(5))
# [1] 0.5454545 #returns 54.54% as the percentile for the value 5
# Not the same answer as quantile produces
【问题讨论】:
***.com/questions/35927956/quantile-vs-ecdf-results 应该会为您提供答案。 【参考方案1】:链接中的答案非常好,但也许有帮助,看看ecdf
只需运行以下代码:
# Simple data
x = 0:10
p0 = 0.5
# Get value corresponding to a percentile using quantile
sapply(c(1:7), function(i) quantile(x, p0, type = i))
# 50% 50% 50% 50% 50% 50% 50%
# 5.0 5.0 5.0 4.5 5.0 5.0 5.0
因此,这不是类型的问题。您可以使用调试单步执行该功能:
# Get percentile corresponding to a value using ecdf function
debug(ecdf)
my_ecdf <- ecdf(x)
关键是
rval <- approxfun(vals, cumsum(tabulate(match(x, vals)))/n,
method = "constant", yleft = 0, yright = 1, f = 0, ties = "ordered")
之后你可以检查
data.frame(x = vals, y = round(cumsum(tabulate(match(x, vals)))/n, 3), stringsAsFactors = FALSE)
当您除以n=11
时,结果并不令人惊讶。如前所述,对于理论,请查看其他答案。
顺便说一句,你也可以绘制函数
plot(my_ecdf)
关于您的评论。我认为这不是可靠性问题,而是如何定义“逆分布函数,如果它不存在”的问题:
一个很好的广义逆参考:Paul Embrechts,Marius Hofert:“A note on generalized inverses”,Math Meth Oper Res (2013) 77:423–432 DOI
【讨论】:
那么答案就是不能可靠地得到分位数函数的反函数吗?我按照你的回答,但它仍然导致分位数函数(第 50 个百分位数 = 5)与 ecdf 函数(5 是第 54.54 个百分位数)之间存在差异。【参考方案2】:ecdf
在文档中给出公式的结果。
x <- 0:10
Fn <- ecdf(x)
现在,Fn
对象是一个插值阶跃函数。
str(Fn)
#function (v)
# - attr(*, "class")= chr [1:3] "ecdf" "stepfun" "function"
# - attr(*, "call")= language ecdf(x)
并且它保留了原始的x
值和对应的y
值。
environment(Fn)$x
# [1] 0 1 2 3 4 5 6 7 8 9 10
environment(Fn)$y
# [1] 0.09090909 0.18181818 0.27272727 0.36363636 0.45454545 0.54545455
# [7] 0.63636364 0.72727273 0.81818182 0.90909091 1.00000000
后者与文档所说的用于计算它们的公式的结果完全相同。来自help('ecdf')
:
对于观测值 x= (x1,x2, ... xn),Fn 是 小于或等于 t 的观测值,即,
Fn(t) = #xi
我将使用seq_along
,而不是1:length(x)
。
seq_along(x)/length(x)
# [1] 0.09090909 0.18181818 0.27272727 0.36363636 0.45454545 0.54545455
# [7] 0.63636364 0.72727273 0.81818182 0.90909091 1.00000000
Fn(x)
# [1] 0.09090909 0.18181818 0.27272727 0.36363636 0.45454545 0.54545455
# [7] 0.63636364 0.72727273 0.81818182 0.90909091 1.00000000
【讨论】:
我在刚刚发布到 Christoph 的回答的评论中提出了同样的问题 @dave_in_newengland 我相信答案是肯定的,只有在极限情况下你会得到相同的值。 ECDF 是一个阶跃函数,每个区间的极值之间的值不一定对应自变量x
的值。在上面的例子中,Fn(5) == 0.54
但分位数是50%
。这不是废话。以上是关于可靠地检索分位数函数的倒数的主要内容,如果未能解决你的问题,请参考以下文章
python使用pandas中的groupby函数和agg函数计算每个分组数据的两个分位数(例如百分之10分位数和百分之90分位数)
Pandas .. 分位数函数是不是需要排序数据来计算百分位数?