stack of KeyedArrays returns a normal array and loses axes information.
d.a is in the code is [1,2,3,4] where this leads to an error, as a keys in each b category should be similar (the a values in the graphic table are correct though )
A working version could be:
@p begin
d
group(_.b)
@aside bnames = collect(keys(__))
map(pairs(__)) do (b, __)
group(_.a)
@aside anames = collect(keys(__))
map(pairs(__)) do (a, __)
[__.x __.y __.z]
end
stack
dropdims(;dims=1)
KeyedArray(;col = [:x, :y, :z], a = anames)
end
@aside anames = only(unique(axiskeys.(__)))[2]
stack
KeyedArray(;col = [:x, :y, :z], a = anames, b = bnames)
end
Note the use of @aside to propagate the keys from group ops, and the explicit check on all a keys being the same in each group.
This is basically unstack in DataFrames lingo. But a generalized version to match unstack could be nice.
@p let
d
group((;_.a), restype=KeyedArray)
map() do gr
KeyedArray([gr.x gr.y gr.z]; gr.b, col=[:x, :y, :z])
end
stack
end
and another grouping-based soluation
@p let
d
group_vg(_.a)
flatmap() do gr
KeyedArray([KeyedArray([gr.x gr.y gr.z]; gr.b, col=[:x, :y, :z])], a=[key(gr)])
end
stack
end
Also, AxisKeys.jl has wrapdims(tbl, :valuecol, :namecols...) that almost does what you want It only supports a single valuecol though, so needs explicit handling of x, y, z:
flatmap([:x, :y, :z]) do c
KeyedArray([wrapdims(columntable(d), c, :a, :b)], col=[c])
end |> stack