Sorting rows of a matrix


Sorting is a fundamental operation in statistical programming, and most SAS programmers are familiar with PROC SORT for sorting data sets. But did you know that you can also sort rows of a SAS/IML matrix according to the value of one or more columns? This post shows how.

Sorting a Matrix In-Place

Not surprisingly, the SAS/IML subroutine that sorts a matrix is the SORT subroutine.

You can sort a matrix by the values in any column or set of columns. You can also specify whether the values in a column should be sorted in ascending or descending order. For example, the following statements sort a matrix by the first column:

proc iml;
x = {5 1 4,
     1 5 1,
     4 3 4,
     2 4 3,
     2 3 1,
     3 2 3};
call sort(x, 1); /** sort x by 1st col **/
print x;

Notice that the matrix x is overwritten by the result. That is, the SORT subroutine sorts the rows of the matrix "in place." In SAS/IML 9.22, the second argument is optional and defaults to 1. Therefore, you can use a simpler statement, call sort(x), to sort a matrix by the first column.

Rows with the same value of the specified column (such as rows 4 and 5 of the original x matrix, which both have a 2 in the first column) appear in the sorted matrix in arbitrary order.

Sorting a Matrix by Values in Multiple Columns

By default, the matrix is sorted so that the specified columns are in ascending order. To sort a matrix in descending order, specify one or more column numbers as the third argument to the SORT subroutine. For example, the following statements sort the rows of the matrix by two columns. The third column is sorted in descending order and ties are broken by sorting the second column in ascending order.

/** sort by 3rd col (descending) and 2nd col **/
call sort(x, {3 2}, 3);
print x;

Sorting a Matrix without Overwriting It

There might be times when you do not want to overwrite a matrix with the sorted version of the matrix. Perhaps you only need to know which row is first in the sorted order. In this case, you can use the SORTNDX subroutine, which returns a vector that contains the row numbers that will sort the matrix. The following statements call the SORTNDX function and print the vector of row numbers:

x = {5 1 4,
     1 5 1,
     4 3 4,
     2 4 3,
     2 3 1,
     3 2 3};
/** get row numbers that sort the matrix **/
call sortndx(idx, x, 1);
print idx;

The idx vector indicates that row 2 is the first row in the sorted matrix, row 5 is the second row in the sorted matrix, and so on, down to row 1, which is the last row in the sorted matrix.

If you want to explicitly sort the x matrix, you can use the idx vector as a row subscript:

y = x[idx, ]; /** y is sorted version of x **/

About Author

Rick Wicklin

Distinguished Researcher in Computational Statistics

Rick Wicklin, PhD, is a distinguished researcher in computational statistics at SAS and is a principal developer of PROC IML and SAS/IML Studio. His areas of expertise include computational statistics, simulation, statistical graphics, and modern methods in statistical data analysis. Rick is author of the books Statistical Programming with SAS/IML Software and Simulating Data with SAS.


  1. Pingback: Sorting a matrix by row or column statistics - The DO Loop

  2. Pingback: Count the number of unique rows in a matrix - The DO Loop

  3. Pingback: An improved simulation of card shuffling - The DO Loop

  4. Amany Hassan on

    How we can sort elements of a matrix row by row? I mean sort the elements of the matrix row by row ascendingly.
    For example, if A={3 5 1 2, 10 7 2 11, 8 4 1 10} and we need it to be sorted such that we have the matrix A after sorting to be A={1 2 3 5, 2 7 10 11, 1 4 8 10}. Thank you.

    • Rick Wicklin

      Loop over the rows. Replace each row with the sorted row:

      do i = 1 to nrow(A);
         v = A[i, ]`;  /* get i_th row; transpose to column vector */
         call sort(v); /* sort it */
         A[i, ] = v`;  /* replace with sorted row */

      You couls also use the SORT function in the DATA step.

Leave A Reply

Back to Top