Skip to content

Commit 55d93f7

Browse files
authored
Fix NaN and missing detection in quantile() (#72)
When `sort=false`, we only partially sort the input, so `NaN`/`missing` is not guaranteed to be in the last position. Also avoid throwing errors for non-`Number` types, for which `isnan` may not be defined.
1 parent fadeeee commit 55d93f7

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

src/Statistics.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -971,8 +971,10 @@ function _quantilesort!(v::AbstractArray, sorted::Bool, minp::Real, maxp::Real)
971971
# only need to perform partial sort
972972
sort!(v, 1, lv, Base.Sort.PartialQuickSort(lo:hi), Base.Sort.Forward)
973973
end
974-
ismissing(v[end]) && throw(ArgumentError("quantiles are undefined in presence of missing values"))
975-
isnan(v[end]) && throw(ArgumentError("quantiles are undefined in presence of NaNs"))
974+
if (sorted && (ismissing(v[end]) || (v[end] isa Number && isnan(v[end])))) ||
975+
any(x -> ismissing(x) || (x isa Number && isnan(x)), v)
976+
throw(ArgumentError("quantiles are undefined in presence of NaNs or missing values"))
977+
end
976978
return v
977979
end
978980

test/runtests.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,15 @@ end
571571
@test quantile(Any[1, Float16(2), 3], Float16(0.5)) isa Float16
572572
@test quantile(Any[1, big(2), 3], Float16(0.5)) isa BigFloat
573573

574-
@test_throws ArgumentError quantile([1, missing], 0.5)
575-
@test_throws ArgumentError quantile([1, NaN], 0.5)
574+
# Need a large vector to actually check consequences of partial sorting
575+
x = rand(50)
576+
for sorted in (false, true)
577+
x[10] = NaN
578+
@test_throws ArgumentError quantile(x, 0.5, sorted=sorted)
579+
x = Vector{Union{Float64, Missing}}(x)
580+
x[10] = missing
581+
@test_throws ArgumentError quantile(x, 0.5, sorted=sorted)
582+
end
576583
@test quantile(skipmissing([1, missing, 2]), 0.5) === 1.5
577584
@test quantile([1], 0.5) === 1.0
578585

0 commit comments

Comments
 (0)