# How to convert wrapped matrix type of KeyedArray

**URL:** https://discourse.julialang.org/t/how-to-convert-wrapped-matrix-type-of-keyedarray/93149
**Category:** General Usage
**Tags:** question, matrices
**Created:** [January 18, 2023, 12:07pm UTC](https://discourse.julialang.org/t/how-to-convert-wrapped-matrix-type-of-keyedarray/93149 "2023-01-18T12:07:52Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![jtackm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jtackm/32/4784_2.png) [@jtackm](https://discourse.julialang.org/u/jtackm)
#### Post date: [January 18, 2023, 12:07pm UTC](https://discourse.julialang.org/t/how-to-convert-wrapped-matrix-type-of-keyedarray/93149/1 "2023-01-18T12:07:53Z")

</div>

Say I have a KeyedArray wrapping a dense matrix:

```julia
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:

```julia
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.

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [January 18, 2023, 12:52pm UTC](https://discourse.julialang.org/t/how-to-convert-wrapped-matrix-type-of-keyedarray/93149/2 "2023-01-18T12:52:40Z")

</div>

Does:

```julia
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?

Another function can be added:

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

A_sparse3 = refill(A, sparse(A))

```

and verifying:

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

```

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [January 18, 2023, 4:01pm UTC](https://discourse.julialang.org/t/how-to-convert-wrapped-matrix-type-of-keyedarray/93149/3 "2023-01-18T16:01:44Z")

</div>

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

```julia
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)...)`.

---

<div class="post-metadata">

### Author: ![jtackm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jtackm/32/4784_2.png) [@jtackm](https://discourse.julialang.org/u/jtackm)
#### Post date: [January 19, 2023, 3:09pm UTC](https://discourse.julialang.org/t/how-to-convert-wrapped-matrix-type-of-keyedarray/93149/4 "2023-01-19T15:09:18Z")

</div>

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