 # Sort matrix based on the elements of a specific column

Hi
I’m new to Julia but I have some exprience with Matlab.
I have an array A (mix of numbers and text columns) and I want to sort the rows based on the values on a specific column of A.
In matlab, the code is:
B = sortrows(A,column)
This sorts A based on the columns specified in the vector column. For example, sortrows(A,4) sorts the rows of A in ascending order based on the elements in the fourth column. sortrows(A,[4 6]) first sorts the rows of A based on the elements in the fourth column, then based on the elements in the sixth column to break ties.

Is there a similar command in Julia? I’ve been looking but not yet found the answer

Thanks in advance for the help!

2 Likes
``````A = rand(1:100, 3, 4)   # a random matrix
A[sortperm(A[:, 4]), :] # sorted by the 4th column
``````

Welcome to Julia!

9 Likes

Here is another:

``````sortrows(A, i, rev=false) = sortslices(A, dims=1, lt=(x,y)->isless(x[i],y[i]), rev=rev)
``````
4 Likes

If your array has a mix of numeric and text columns, you probably want to be using a DataFrame instead. The DataFrames package comes with methods for sorting by column name or index:

``````julia> using DataFrames
julia> df = DataFrame(a = ["b", "a", "a"], x = [4.2, 0, -5.1],
y = [3//2, -1//2, 15//16]);
julia> sort(df, :a)
3×3 DataFrame
│ Row │ a      │ x       │ y         │
│     │ String │ Float64 │ Rational… │
├─────┼────────┼─────────┼───────────┤
│ 1   │ a      │ 0.0     │ -1//2     │
│ 2   │ a      │ -5.1    │ 15//16    │
│ 3   │ b      │ 4.2     │ 3//2      │

julia> sort(df, 1)
3×3 DataFrame
│ Row │ a      │ x       │ y         │
│     │ String │ Float64 │ Rational… │
├─────┼────────┼─────────┼───────────┤
│ 1   │ a      │ 0.0     │ -1//2     │
│ 2   │ a      │ -5.1    │ 15//16    │
│ 3   │ b      │ 4.2     │ 3//2      │
``````

or by multiple columns:

``````julia> sort(df, [:a, :x])
3×3 DataFrame
│ Row │ a      │ x       │ y         │
│     │ String │ Float64 │ Rational… │
├─────┼────────┼─────────┼───────────┤
│ 1   │ a      │ -5.1    │ 15//16    │
│ 2   │ a      │ 0.0     │ -1//2     │
│ 3   │ b      │ 4.2     │ 3//2      │
``````
2 Likes

I had the same issue, but I needed to break ties and didn’t want to use DataFrames. Here is a suggestion (the default behavior is like Matlab’s, otherwise one can specify a matrix of elements to sort on):

``````function sortrows(M, by=zeros(0))
if by == zeros(0)
order = copy(M)
else
order = copy(by)
end
if size(order,2) > 1
order = Float64.(order.-minimum(order, dims = 1))
order = (order./maximum(order,dims=1))*(10).^(size(order,2):-1:1)
end
order = sortperm(order[:,1])
return M[order,:], order
end

A = [4 1 1; 3 2 5;2 4 3]'
sorted_A, order = sortrows(A,A[:,[1,3]])

julia> sorted_A
3×3 Array{Int64,2}:
1  5  3
1  2  4
4  3  2
``````

In Julia 1.4.2:

`````` # generate random matrix
A = rand(4,3)

# sort by row (dim=1) along column 2
sortslices(A,dims=1,by=x->x,rev=false)

# reverse sort by row (dim=1) along column 2
sortslices(A,dims=1,by=x->x,rev=true)
``````
5 Likes