Unsure about counts and proportions

isequal(proportions([1, 2, 2, 3, 4, 5, 5, 5, 7, 7], s1), counts([1, 2, 2, 3, 4, 5, 5, 5, 7, 7], s1)/length([1, 2, 2, 3, 4, 5, 5, 5, 7, 7]))
when s1 = span([1, 2, 2, 3, 4, 5, 5, 5, 7, 7])
gives false while

proportions([1, 2, 2, 3, 4, 5, 5, 5, 7, 7], s1) gives equal vector as of counts([1, 2, 2, 3, 4, 5, 5, 5, 7, 7], s1)/length([1, 2, 2, 3, 4, 5, 5, 5, 7, 7])) and both are of same types.

Seems to be a problem of floating point precision:

julia> using StatsBase

julia> isapprox(proportions([1, 2, 2, 3, 4, 5, 5, 5, 7, 7], s1), counts([1, 2, 2, 3, 4, 5, 5, 5, 7, 7], s1)/length([1, 2, 2, 3, 4, 5, 5, 5, 7, 7]))
true

The documentations says:

help?> proportions
...
Equivalent to counts(x, levels) / length(x)
...

which seems to be wrong:

julia> @less proportions(x,s)

...
proportions(x::IntegerArray, levels::IntUnitRange) = counts(x, levels) .* inv(length(x))
...

Therefore:

julia> using StatsBase

julia> x=[1, 2, 2, 3, 4, 5, 5, 5, 7, 7]

julia> s=span(x)

julia> proportions(x,s)

julia> counts(x, s) .* inv(length(x))

julia> isequal(proportions(x,s),counts(x, s) .* inv(length(x)))
true

Opening an issue (or better a PR) regarding the documentation would be appropriate, I guess:
https://juliastats.org/StatsBase.jl/stable/counts/#StatsBase.proportions

Some more example to show the underlying floating point precision issue here:

julia> 3/10
0.3

julia> 3*0.1
0.30000000000000004
1 Like