Я написал функцию, подобную следующей:
gini(v::Array{<:Real,1}) = (2 * sum([x*i for (i,x) in enumerate(sort(v))]) / sum(sort(v)) - (length(v)+1))/(length(v))
Эта функция хорошо работает при передаче Vector
или DataFrame
. Например:
gini(collect(1:1:10))
# 0.3
или
using DataFrames # DataFrames v1.3.2
df = DataFrame(v = collect(1:1:10),
group = repeat([1, 2], 5))
combine(df, :v => gini)
#1×1 DataFrame
# Row │ v_gini
# │ Float64
#─────┼─────────
# 1 │ 0.3
Однако, в отличие от других функций, которые принимают векторы в качестве аргумента (например, Statistics.mean
), она выдает MethodError
при передаче GroupedDataFrame
.
combine(groupby(df, :group), :v => gini)
# nested task error: MethodError: no method matching #gini(::SubArray{Int64, 1, Vector{Int64}, Tuple{SubArray{Int64, 1, #Vector{Int64}, Tuple{UnitRange{Int64}}, true}}, false})
# Closest candidates are:
# gini(::Vector{<:Real})
Как я могу написать функции, подобные приведенной выше, которые работают при передаче GroupedDataFrame
?
Вам нужно изменить подпись метода на:
gini(v::AbstractVector{<:Real})
Дело в том, что combine
передает представление вектора (у которого не Vector
тип, а SubArray
). Поэтому вам нужно разрешить любые векторы вашей функцией, а не только Vector
.