@@ -626,7 +626,7 @@ is strictly superior to ``h``. The weighted ``p`` quantile is given by ``v_k +
626626with ``γ = (h - S_k)/(S_{k+1} - S_k)``. In particular, when all weights are equal,
627627the function returns the same result as the unweighted `quantile`.
628628"""
629- function quantile (v:: AbstractVector{V} , w:: AbstractWeights{W} , p:: AbstractVector{<:Real} ) where {V<: Real , W<: Real }
629+ function quantile (v:: AbstractVector{V} , w:: AbstractWeights{W} , p:: AbstractVector{<:Real} ) where {V, W<: Real }
630630 # checks
631631 isempty (v) && throw (ArgumentError (" quantile of an empty array is undefined" ))
632632 isempty (p) && throw (ArgumentError (" empty quantile array" ))
@@ -650,21 +650,29 @@ function quantile(v::AbstractVector{V}, w::AbstractWeights{W}, p::AbstractVector
650650 vw = sort! (collect (zip (view (v, nz), view (w, nz))))
651651 N = length (vw)
652652
653+ # missing is always sorted last
654+ if ismissing (vw[end ][1 ])
655+ throw (ArgumentError (" quantiles are undefined in presence of missing values" ))
656+ end
657+
653658 # prepare percentiles
654659 ppermute = sortperm (p)
655660 p = p[ppermute]
656661
657662 # prepare out vector
658- out = Vector {typeof(zero(V)/1)} (undef, length (p))
663+ v1 = vw[1 ][1 ]
664+ out = Vector {typeof(v1 + zero(eltype(p))*zero(W)*zero(v1))} (undef, length (p))
659665 fill! (out, vw[end ][1 ])
660666
661- for x in v
662- isnan (x) && return fill! (out, x)
667+ # NaN is always sorted last in the absence of missing
668+ # This behavior isn't consistent with Statistics.quantile, but preserve it for backward compatibility
669+ if vw[end ][1 ] isa Number && isnan (vw[end ][1 ])
670+ return fill (vw[end ][1 ], length (p))
663671 end
664672
665673 # loop on quantiles
666674 Sk, Skold = zero (W), zero (W)
667- vk, vkold = zero (V ), zero (V )
675+ vk, vkold = zero (v1 ), zero (v1 )
668676 k = 0
669677
670678 w1 = vw[1 ][2 ]
@@ -693,19 +701,19 @@ function quantile(v::AbstractVector{V}, w::AbstractWeights{W}, p::AbstractVector
693701 return out
694702end
695703
696- function quantile (v:: AbstractVector{<:Real} , w:: UnitWeights , p:: AbstractVector{<:Real} )
704+ function quantile (v:: AbstractVector , w:: UnitWeights , p:: AbstractVector{<:Real} )
697705 length (v) != length (w) && throw (DimensionMismatch (" Inconsistent array dimension." ))
698706 return quantile (v, p)
699707end
700708
701- quantile (v:: AbstractVector{<:Real} , w:: AbstractWeights{<:Real} , p:: Number ) = quantile (v, w, [p])[1 ]
709+ quantile (v:: AbstractVector , w:: AbstractWeights , p:: Real ) = quantile (v, w, [p])[1 ]
702710
703711# #### Weighted median #####
704712
705713"""
706- median(v::AbstractVector{<:Real} , w::AbstractWeights)
714+ median(v::AbstractVector, w::AbstractWeights)
707715
708716Compute the weighted median of `v` with weights `w`
709717(of type `AbstractWeights`). See the documentation for [`quantile`](@ref) for more details.
710718"""
711- median (v:: AbstractVector{<:Real} , w:: AbstractWeights{<:Real} ) = quantile (v, w, 0.5 )
719+ median (v:: AbstractVector , w:: AbstractWeights ) = quantile (v, w, 0.5 )
0 commit comments