spatstat 包中的加权中位数

weighted median in spatstat package

spatstat package returns "10.5", when I pass the evenly weighted scores of 10, 11, & 12. I was expecting the response of "11" (which is the output of stats::median() and matrixStats::weightedMedian() 中的 weighted.median() 函数。

加权中位数的概念对我来说不是很自然。输出不正确,还是我误解了函数的用途?

x <- c(10, 11, 12)
w <- c( 1,  1,  1)

spatstat::weighted.median(x, w)
#> [1] 10.5
spatstat::weighted.quantile(x, w, probs = .5)
#>  50% 
#> 10.5


matrixStats::weightedMedian(x, w)
#> [1] 11
median(x)
#> [1] 11

reprex package (v0.3.0)

于 2020-02-23 创建

我认为这是软件包中的一个缺陷,我会解释原因。

首先,weighted.median 实际上只是调用 weighted.quantile,并将 probs 向量设置为 0.5。但是如果你用你的数据调用 weighted.quantile,你会得到非常奇怪的结果:

weighted.quantile(x, w)
#>    0%   25%   50%   75%  100% 
#> 10.00 10.00 10.50 11.25 12.00 

不对。

如果您使用 body(weighted.quantile) 查看此函数的主体,并遵循逻辑,第 10 行将权重归一化为名为 [=20 的变量的方式似乎存在问题=].为了正常工作,归一化权重应该是一个与 x 长度相同的向量,但从 0 开始到 1 结束,两者之间的间距与权重成正比。

但是如果你看看这实际上是如何计算的:

body(weighted.quantile)[[10]]
#> Fx <- cumsum(w)/sum(w)

你可以看到它不是从 0 开始的。在你的例子中,第一个元素是 0.3333。

为了证明是这样,让我们​​用正确的表达方式重写这一行。 (首先我们需要解锁绑定才能访问该功能)

unlockBinding("weighted.quantile", asNamespace("spatstat"))
body(weighted.quantile)[[10]] <- substitute(Fx <- (cumsum(w) - min(w))/(sum(w) - min(w)))

现在我们得到了加权分位数的正确结果(包括正确的中位数)

weighted.quantile(x, w)
#>   0%  25%  50%  75% 100% 
#> 10.0 10.5 11.0 11.5 12.0 

这里有一个更基本的问题,关于小有限样本中分位数(包括中位数)的定义。

R基函数quantile.default的帮助文件说有一个参数type,有7个不同的选项,会给出不同的答案。 Rob Hyndman 在帮助文件中引用的一篇精彩文章中详细描述了这些内容。 quantile.default 的默认值为 type=7

spatstat::weighted.quantile中的算法执行type=4的模拟(根据其帮助文件);即,对累积分布函数 F(x) 进行线性插值,然后计算反函数。 该算法已在 spatstat 代码中正确实现。

您提到的另一个包中的加权中位数正在计算加权中位数的不同定义。

非常感谢您提请我们注意这个例子。这可能会促使我们扩展 spatstat::weighted.median 的实现以包含其他类型。

顺便说一句,CRAN 包的错误报告应该posted 在包的错误报告页面上,如 CRAN 上所示。很幸运我看到了这个post。但非常感谢你们发现这个问题。