AxisKeys.jl icon indicating copy to clipboard operation
AxisKeys.jl copied to clipboard

`wrapdims` doesn't work when axis eltype is `UnitRange`

Open jariji opened this issue 6 months ago • 1 comments

It works when the eltype is a tuple of ints, but not when it's a range.

julia> wrapdims(DataFrame(a=[(1,2), (3,4)], b=[10, 20], c=[100, 200]), :c, :a, :b)
2-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓   a ∈ 2-element Vector{Tuple{Int64, Int64}}
→   b ∈ 2-element Vector{Int64}
And data, 2×2 Matrix{Int64}:
            (10)  (20)
   (1, 2)    100     0
   (3, 4)      0   200

julia> wrapdims(DataFrame(a=[(1:2), (3:4)], b=[10, 20], c=[100, 200]), :c, :a, :b)
ERROR: ArgumentError: could not find key 1 in vector UnitRange{Int64}[1:2, 3:4]
Stacktrace:
  [1] findindex
    @ ~/.julia/packages/AxisKeys/sYP4R/src/lookup.jl:80 [inlined]
  [2] (::AxisKeys.var"#15#16"{Vector{UnitRange{Int64}}})(x::Int64)
    @ AxisKeys ./none:0
  [3] iterate
    @ ./generator.jl:48 [inlined]
  [4] collect
    @ ./array.jl:791 [inlined]
  [5] findindex
    @ ~/.julia/packages/AxisKeys/sYP4R/src/lookup.jl:86 [inlined]
  [6] map
    @ ./tuple.jl:383 [inlined]
  [7] populate_function_barrier!(A::KeyedArray{…}, value_column::Vector{…}, axis_key_columns::Tuple{…}, mask::BitMatrix, force::Bool)
    @ AxisKeys ~/.julia/packages/AxisKeys/sYP4R/src/tables.jl:153
  [8] populate!(A::KeyedArray{Int64, 2, NamedDimsArray{…}, Tuple{…}}, table::DataFrame, value::Symbol; force::Bool)
    @ AxisKeys ~/.julia/packages/AxisKeys/sYP4R/src/tables.jl:144
  [9] populate!(A::KeyedArray{Int64, 2, NamedDimsArray{…}, Tuple{…}}, table::DataFrame, value::Symbol)
    @ AxisKeys ~/.julia/packages/AxisKeys/sYP4R/src/tables.jl:137
 [10] _wrap_table(::Type{…}, ::typeof(identity), ::DataFrame, ::Symbol, ::Symbol, ::Vararg{…}; default::UndefInitializer, sort::Bool, kwargs::@Kwargs{})
    @ AxisKeys ~/.julia/packages/AxisKeys/sYP4R/src/tables.jl:277
 [11] _wrap_table(::Type, ::Function, ::DataFrame, ::Symbol, ::Symbol, ::Vararg{Symbol})
    @ AxisKeys ~/.julia/packages/AxisKeys/sYP4R/src/tables.jl:253
 [12] wrapdims(::DataFrame, ::Symbol, ::Symbol, ::Vararg{Symbol}; kw::@Kwargs{})
    @ AxisKeys ~/.julia/packages/AxisKeys/sYP4R/src/tables.jl:232
 [13] wrapdims(::DataFrame, ::Symbol, ::Symbol, ::Symbol, ::Vararg{Symbol})
    @ AxisKeys ~/.julia/packages/AxisKeys/sYP4R/src/tables.jl:230
 [14] top-level scope

jariji avatar Jun 26 '25 06:06 jariji

I think it arises because collections (include UnitRanges) are treated as multiple elements in lookup:

julia> KeyedArray([1, 2], a=[(1:2), (3:4)])
1-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓   a ∈ 2-element Vector{UnitRange{Int64}}
And data, 2-element Vector{Int64}:
 (1:2)  1
 (3:4)  2

julia> A(a=1:2)
ERROR: ArgumentError: could not find key 1 in vector UnitRange{Int64}[1:2, 3:4]

It tries to find both 1 and 2, not the actual object 1:2. Idk what would be a better semantic... Maybe wrapdims shouldn't use lookup directly?

aplavin avatar Jun 26 '25 08:06 aplavin