I believe this is a flaw in the package, and I'll explain why.
Firstly, weighted.median
actually just calls weighted.quantile
with the probs
vector set to 0.5
. But if you call weighted.quantile
with your data, you get very strange results:
weighted.quantile(x, w)
#> 0% 25% 50% 75% 100%
#> 10.00 10.00 10.50 11.25 12.00
That's not right.
If you look at the body of this function using body(weighted.quantile)
, and follow the logic through, there seems to be a problem with the way the weights are normalized on line 10 into a variable called Fx
. To work properly, the normalized weights should be a vector of the same length as x
, but starting at 0 and ending in 1, with the spacing in between being proportional to the weights.
But if you look at how this is actually calculated:
body(weighted.quantile)[[10]]
#> Fx <- cumsum(w)/sum(w)
You can see it doesn't start at 0. In your case, the first element would be 0.3333.
So to show this is the case, let's write over this line with the correct expression. (First we need to unlock the binding to give access to the function)
unlockBinding("weighted.quantile", asNamespace("spatstat"))
body(weighted.quantile)[[10]] <- substitute(Fx <- (cumsum(w) - min(w))/(sum(w) - min(w)))
Now we get the correct result for weighted quantiles (including the correct median)
weighted.quantile(x, w)
#> 0% 25% 50% 75% 100%
#> 10.0 10.5 11.0 11.5 12.0