Sort rows and columns of NamedArray

I am working with a frequency table that is based on a NamedArray. I am having trouble reverse sorting the dimensions. Here is an example:

n = NamedArray([1 3; 2 4], ( ["a", "b"], ["c", "d"] ), ("Rows", "Cols"))

Result:

2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
a           │ 1  3
b           │ 2  4

Next, I try to reverse sort on dimension 1

sort!(n, dims=1, rev=true)

Result:

Rows ╲ Cols │ c  d
────────────┼─────
a           │ 2  4
b           │ 1  3

Notice that the values in the rows were reversed, but not the names (a, b). How to I sort values and names? Thanks!

Edit: I realize this can be accomplished with setnames! and sort, but I was wondering if there is a way to do it with a single function.

The problem is not well defined. Consider:

julia> n = NamedArray([1 3; 4 2], ( ["a", "b"], ["c", "d"] ), ("Rows", "Cols"))
2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
a           │ 1  3
b           │ 4  2

julia> sort!(n, dims=1, rev=true)
2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
a           │ 4  3
b           │ 1  2

As the row entries are not necessarily kept together, there is no rule for row names.
So, you have to do it according to your own rules in the way which fits for you.

Yeah. I see the problem. I want to sort the rows, not the values independently within the rows. Is there a way to change the order of the names such that the values stay with them? For example:

julia> n = NamedArray([4 2; 1 3], ( ["b", "a"], ["c", "d"] ), ("Rows", "Cols"))
2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
b           │ 4  2
a           │ 1  3

I suppose one approach is to index and create a copy:

julia> n[["b","a"],:]
2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
b           │ 4  2
a           │ 1  3

Still not uniquely clear.
I assume you want from

julia> n = NamedArray([4 2; 1 3], ( ["b", "a"], ["c", "d"] ), ("Rows", "Cols"))
2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
b           │ 4  2
a           │ 1  3

get it sorted like:

2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
a           │ 1  3
b           │ 4  2

So, every row still contains same column value pairs but the rows are sorted regarding all column values, with the first column highest precedence, then second and so on.
I can’t do it with sort!, thats my solution:

julia> n = NamedArray([4 2; 1 3], ( ["b", "a"], ["c", "d"] ), ("Rows", "Cols"))
2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
b           │ 4  2
a           │ 1  3

julia> p = sort(1:size(n,1); lt = (x,y)->Tuple(n[x,:])<Tuple(n[y,:]) ) #p=permutation
2-element Array{Int64,1}:
 2
 1

julia> n[p,:]
2×2 Named Array{Int64,2}
Rows ╲ Cols │ c  d
────────────┼─────
a           │ 1  3
b           │ 4  2

Typically others will present much better solutions in a while :wink:

1 Like

Much appreciated. Thank you!