diff --git a/src/abstractdataframe/abstractdataframe.jl b/src/abstractdataframe/abstractdataframe.jl index 41539befe7..6821cbd700 100644 --- a/src/abstractdataframe/abstractdataframe.jl +++ b/src/abstractdataframe/abstractdataframe.jl @@ -703,10 +703,23 @@ function get_stats(@nospecialize(col::Union{AbstractVector, Base.SkipMissing}), d = Dict{Symbol, Any}() if :q25 in stats || :median in stats || :q75 in stats - q = try quantile(col, [.25, .5, .75]) catch; (nothing, nothing, nothing) end - d[:q25] = q[1] - d[:median] = q[2] - d[:q75] = q[3] + # types that do not support basic arithmetic (like strings) will only fail + # after sorting the data, so check this beforehand to fail early + T = eltype(col) + if isconcretetype(T) && !hasmethod(-, Tuple{T, T}) + d[:q25] = d[:median] = d[:q75] = nothing + else + mcol = Base.copymutable(col) + if :q25 in stats + d[:q25] = try quantile!(mcol, 0.25) catch; nothing; end + end + if :median in stats + d[:median] = try quantile!(mcol, 0.50) catch; nothing; end + end + if :q75 in stats + d[:q75] = try quantile!(mcol, 0.75) catch; nothing; end + end + end end if :min in stats || :max in stats diff --git a/test/dataframe.jl b/test/dataframe.jl index a00e432650..e69392710c 100644 --- a/test/dataframe.jl +++ b/test/dataframe.jl @@ -668,7 +668,7 @@ end nothing, nothing, nothing], min = [1.0, 1.0, "a", "a", Date(2000), 1], q25 = [1.75, 1.5, nothing, nothing, nothing, nothing], - median = [2.5, 2.0, nothing, nothing, nothing, nothing], + median = [2.5, 2.0, nothing, nothing, VERSION >= v"1.7.0-beta1.2" ? Date(2002) : nothing, nothing], q75 = [3.25, 2.5, nothing, nothing, nothing, nothing], max = [4.0, 3.0, "d", "c", Date(2004), 2], nunique = [nothing, nothing, 4, 3, 4, 2],