davidavdav / NamedArrays.jl

Julia type that implements a drop-in replacement of Array with named dimensions
Other
118 stars 20 forks source link

Getting the names along a named axis #130

Closed njericha closed 1 month ago

njericha commented 1 year ago

It seams reasonable to ask names() for the names along a particular dimension, given the dimension name. Currently, you must know the dimension number to get the names along that axis. For example:

julia> n = NamedArray([1 2; 3 4], (["a", "b"], ["one", "two"]), ("A", "B"))
2×2 Named Matrix{Int64}
A ╲ B │ one  two
──────┼─────────
a     │   1    2
b     │   3    4

julia> names(n, 1)
2-element Vector{String}:
 "a"
 "b"

julia> names(n, "A")
ERROR: MethodError: no method matching names(::NamedMatrix{Int64, Matrix{Int64}, Tuple{OrderedCollections.OrderedDict{String, Int64}, OrderedCollections.OrderedDict{String, Int64}}}, ::String)
[...]

where I would expect names(n, "A") == ["a", "b"].

My current hack/solution is adding a method to names() that finds the matching dimension name from all the dimnames(n) like so:

function Base.names(n::NamedArray, dimname::Union{String,Symbol})
    return names(n, findfirst(dimnames(n) .== dimname))
end
davidavdav commented 1 year ago

Definitively a reasonable request. I can foresee a potential problem when you give integer dimensions to the names:

julia> n = NamedArray(rand(2,2), (["a", "b"], ["one", "two"]), (2, 1))

In such a case I would say that

julia> names(n, 1)
2-element Vector{String}:
 "a"
 "b"

julia> names(n, Name(1))
2-element Vector{String}:
 "one"
 "two"