在 Julia 中寻找分位数

Finding quantiles in Julia

我需要像 Stata 中的 xtile 这样的函数,给定一个向量,它 returns 每个 obs 属于哪个分位数。所以如果函数定义为

function xtile(vector; q= 4) #q = 4 by default returns quartiles
    *** returns a vector with the same size as "vector", indicating which quantile each obs belongs to.
end

我想用在:

@pipe df |> transform(:height => xtile => :quantiles)

我知道Stella.jl提供了这样的功能。但是我不能安装那个包,现在我想知道是否有另一个包。或者我可以自己实现。

可以在 cut method provided by the CategoricalArrays.jl package 中找到现成的解决方案,只要您对 StringsAbstractVector 满意:

using CategoricalArrays

x = rand(10);
cut(x, 4)
# 10-element CategoricalArray{String,1,UInt32}:
#  "Q4: [0.565838, 0.85564]"
#  "Q2: [0.333373, 0.393529)"
#  "Q4: [0.565838, 0.85564]"
#  "Q3: [0.393529, 0.565838)"
#  "Q1: [0.0381196, 0.333373)"
#  "Q3: [0.393529, 0.565838)"
#  "Q4: [0.565838, 0.85564]"
#  "Q1: [0.0381196, 0.333373)"
#  "Q1: [0.0381196, 0.333373)"
#  "Q2: [0.333373, 0.393529)"

如果你想要分位数为数字,你可以通过广播获得级别代码levelcode:

a = cut(x, 4);
levelcode.(a)
# 10-element Array{Int64,1}:
#  4
#  2
#  4
#  3
#  1
#  3
#  4
#  1
#  1
#  2

这可以很容易地转换为在管道中工作的函数:

xtile(x; n=4) = levelcode.(cut(x, n));
xtile(x)
# 10-element Array{Int64,1}:
#  4
#  2
#  4
#  3
#  1
#  3
#  4
#  1
#  1
#  2

xtile(x, n=5)
# 10-element Array{Int64,1}:
#  4
#  2
#  5
#  4
#  1
#  3
#  5
#  2
#  1
#  3

虽然使用 CategoricalArrays 包是一个很好的解决方案,并且具有实际显示分位数含义的额外好处,但仅使用 Julia 标准库就可以很容易地实现 xtile

using Statistics
function xtile(x; n=4)
    q = quantile(x, LinRange(0, 1, n + 1))
    map(v -> min(searchsortedlast(q, v), n), x)
end