# How to convert wrapped matrix type of KeyedArray

Say I have a KeyedArray wrapping a dense matrix:

``````using AxisKeys, Random
n = 100
A = KeyedArray(rand(0:1, n, n), dim1=["a\$i" for i in 1:n], dim2=["b\$i" for i in 1:n])

2-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓   dim1 ∈ 100-element Vector{String}
→   dim2 ∈ 100-element Vector{String}
And data, 100×100 Matrix{Int64}:
("b1")  ("b2")  ("b3")  …  ("b97")  ("b98")  ("b99")  ("b100")
("a1")     0       0       0          0        1        1        1
("a2")     1       0       0          1        0        1        0
("a3")     1       1       0          1        0        0        0
("a4")     0       1       0          1        1        0        0
("a5")     1       1       1      …   0        0        0        0
("a6")     0       1       0          0        1        1        1
⋮                                ⋱                     ⋮
("a94")    1       1       0          1        0        1        1
("a95")    0       0       1          0        1        1        1
("a96")    1       0       1      …   0        1        0        0
("a97")    0       0       1          0        0        1        0
("a98")    1       1       1          1        0        0        0
("a99")    0       0       0          0        1        0        0
("a100")   0       1       1          0        1        1        1
``````

What is the easiest way to convert the underlying matrix type (say from dense to sparse) without changing axis information? My best solution so far is quite unwieldy:

``````using SparseArrays
A_sparse = KeyedArray(sparse(A); (dimnames(A) .=> axiskeys(A))...)

2-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓   dim1 ∈ 100-element Vector{String}
→   dim2 ∈ 100-element Vector{String}
And data, 100×100 SparseMatrixCSC{Int64, Int64} with 5028 stored entries:
("b1")  ("b2")  ("b3")  …  ("b97")  ("b98")  ("b99")  ("b100")
("a1")     0       0       0          0        1        1        1
("a2")     1       0       0          1        0        1        0
("a3")     1       1       0          1        0        0        0
("a4")     0       1       0          1        1        0        0
("a5")     1       1       1      …   0        0        0        0
("a6")     0       1       0          0        1        1        1
⋮                                ⋱                     ⋮
("a94")    1       1       0          1        0        1        1
("a95")    0       0       1          0        1        1        1
("a96")    1       0       1      …   0        1        0        0
("a97")    0       0       1          0        0        1        0
("a98")    1       1       1          1        0        0        0
("a99")    0       0       0          0        1        0        0
("a100")   0       1       1          0        1        1        1
``````

Of course I could define a function, but I’m thinking there must be a build-in option I’m missing.

Does:

``````refill(na::NamedDimsArray{X},m) where X =
NamedDimsArray{X,eltype(m),ndims(m),typeof(m)}(m)

A_sparse2 = KeyedArray(refill(parent(A), sparse(A)), axiskeys(A))
``````

seem less unwieldy?

``````refill(ka::KeyedArray,m) =
( na = refill(parent(ka),m) ; KeyedArray(na, axiskeys(ka)) )

A_sparse3 = refill(A, sparse(A))
``````

and verifying:

``````julia> A_sparse == A_sparse2 == A_sparse3
true
``````

With `Accessors`, you can conveniently apply `sparse` to `AxisKeys.keyless_unname(A)`, and store the result back:

``````julia> using AccessorsExtra

julia> A_sparse = @modify(sparse, AxisKeys.keyless_unname(A))
2-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓   dim1 ∈ 100-element Vector{String}
→   dim2 ∈ 100-element Vector{String}
And data, 100×100 SparseMatrixCSC{Int64, Int64} with 5001 stored entries:
("b1")  ("b2")  ("b3")  …  ("b98")  ("b99")  ("b100")
("a1")     0       0       1          0        0        0
...
``````

Btw, even without extra packages, your `KeyedArray(sparse(A); (dimnames(A) .=> axiskeys(A))...)` can be simplified to `KeyedArray(sparse(A); named_axiskeys(A)...)`.

Thanks for the suggestions! I didn’t know about `named_axiskeys`, that is pretty much what I had in mind