我需要一个像xtileStata 中的函数,给定一个向量,它返回每个 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
Run Code Online (Sandbox Code Playgroud)
我想在以下方面使用它:
@pipe df |> transform(:height => xtile => :quantiles)
Run Code Online (Sandbox Code Playgroud)
我知道Stella.jl提供了这样的功能。但是我无法安装该软件包,现在我想知道是否还有其他软件包。或者我可以自己实现它。
虽然使用 CategoricalArrays 包是一个很好的解决方案,并且具有实际显示分位数含义的额外好处,但xtile仅使用 Julia 标准库就很容易实现:
using Statistics
function xtile(x; n=4)
q = quantile(x, LinRange(0, 1, n + 1))
map(v -> min(searchsortedlast(q, v), n), x)
end
Run Code Online (Sandbox Code Playgroud)
只要您同意以下方法,就可以使用包提供的cut方法找到现成的解决方案:CategoricalArrays.jlAbstractVectorStrings
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)"
Run Code Online (Sandbox Code Playgroud)
如果您想要分位数作为数字,您可以通过广播获取级别代码levelcode:
a = cut(x, 4);
levelcode.(a)
# 10-element Array{Int64,1}:
# 4
# 2
# 4
# 3
# 1
# 3
# 4
# 1
# 1
# 2
Run Code Online (Sandbox Code Playgroud)
这可以很容易地转换为在管道中工作的函数:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
301 次 |
| 最近记录: |