@@ -333,11 +333,17 @@ function find_breaks(v::AbstractVector, qs::AbstractVector)
333333    return  breaks
334334end 
335335
336+ #  AbstractWeights method is defined in StatsBase extension
337+ #  There is no in-place weighted quantile method in StatsBase
338+ _wquantile (x:: AbstractArray , w:: AbstractVector , p:: AbstractVector ) = 
339+     throw (ArgumentError (" `weights` must be an `AbstractWeights` vector from StatsBase.jl"  ))
340+ 
336341""" 
337342    cut(x::AbstractArray, ngroups::Integer; 
338343        labels::Union{AbstractVector{<:AbstractString},Function}, 
339344        sigdigits::Integer=3, 
340-         allowempty::Bool=false) 
345+         allowempty::Bool=false, 
346+         weights::Union{AbstractWeights, Nothing}=nothing) 
341347
342348Cut a numeric array into `ngroups` quantiles. 
343349
@@ -369,19 +375,40 @@ quantiles.
369375  other than the last one are equal, generating empty intervals; 
370376  when `true`, duplicate breaks are allowed and the intervals they generate are kept as 
371377  unused levels (but duplicate labels are not allowed). 
378+ * `weights::Union{AbstractWeights, Nothing}=nothing`: observations weights to pass to `quantile`. 
372379""" 
373380function  cut (x:: AbstractArray , ngroups:: Integer ;
374381             labels:: Union{AbstractVector{<:SupportedTypes},Function,Nothing} = nothing ,
375382             sigdigits:: Integer = 3 ,
376-              allowempty:: Bool = false )
383+              allowempty:: Bool = false ,
384+              weights:: Union{AbstractVector, Nothing} = nothing )
377385    ngroups >=  1  ||  throw (ArgumentError (" ngroups must be strictly positive (got $ngroups )"  ))
378-     sorted_x =  eltype (x) >:  Missing  ?  sort! (collect (skipmissing (x))) :  sort (x)
379-     min_x, max_x =  first (sorted_x), last (sorted_x)
380-     if  (min_x isa  Number &&  isnan (min_x)) || 
381-         (max_x isa  Number &&  isnan (max_x))
382-         throw (ArgumentError (" NaN values are not allowed in input vector"  ))
386+     if  weights ===  nothing 
387+         sorted_x =  eltype (x) >:  Missing  ?  sort! (collect (skipmissing (x))) :  sort (x)
388+         min_x, max_x =  first (sorted_x), last (sorted_x)
389+         if  (min_x isa  Number &&  isnan (min_x)) || 
390+             (max_x isa  Number &&  isnan (max_x))
391+             throw (ArgumentError (" NaN values are not allowed in input vector"  ))
392+         end 
393+         qs =  quantile! (sorted_x, (1 : (ngroups- 1 ))/ ngroups, sorted= true )
394+     else 
395+         if  eltype (x) >:  Missing 
396+             nm_inds =  findall (! ismissing, x)
397+             nm_x =  view (x, nm_inds)
398+             #  TODO : use a view once this is supported (JuliaStats/StatsBase.jl#723)
399+             nm_weights =  weights[nm_inds]
400+         else 
401+             nm_x =  x
402+             nm_weights =  weights
403+         end 
404+         sorted_x =  sort (nm_x)
405+         min_x, max_x =  first (sorted_x), last (sorted_x)
406+         if  (min_x isa  Number &&  isnan (min_x)) || 
407+             (max_x isa  Number &&  isnan (max_x))
408+             throw (ArgumentError (" NaN values are not allowed in input vector"  ))
409+         end 
410+         qs =  _wquantile (nm_x, nm_weights, (1 : (ngroups- 1 ))/ ngroups)
383411    end 
384-     qs =  quantile! (sorted_x, (1 : (ngroups- 1 ))/ ngroups, sorted= true )
385412    breaks =  [min_x; find_breaks (sorted_x, qs); max_x]
386413    if  ! allowempty &&  ! allunique (@view  breaks[1 : end - 1 ])
387414        throw (ArgumentError (" cannot compute $ngroups  quantiles due to "   * 
0 commit comments