Infix operators for custom row- and column-wise re-ordering of matrices.
The x %row~% mat
operator re-orders the elements of every row,
each row ordered independently from the other rows, of matrix x
,
according to the ordering ranks given in matrix mat
.
The x %col~% mat
operator re-orders the elements of every column,
each column ordered independently from the other columns, of matrix x
,
according to the ordering ranks given in matrix mat
.
Arguments
- x
a matrix
- mat
a matrix with the same dimensions as
x
, giving the ordering ranks of every element of matrixx
.
Details
If matrix x
is a numeric matrix,
and one wants to sort the elements of every row or column numerically,
x %row~% x
or x %col~% x
would suffice, respectively.
If matrix x
is not numeric,
sorting the elements using x %row~% x
and x %col~% x
is still possible,
but probably not the best option.
In the non-numeric case,
providing a matrix of ordering ranks for mat
would be faster and give more accurate ordering.
See the examples section.
If mat
is a matrix of non-repeating random integers, i.e. mat <- sample(seq_along(x)) |> matrix(ncol = ncol(x))
)
then the code x %row~% mat
will randomly shuffle the elements of every row of x
,
where the shuffling order in each row is independent from the shuffling order in the other rows.
Similarly, x %col~% mat
will randomly shuffle the elements of every column of x
,
where the shuffling order in each column is independent from the shuffling order in the other columns.
Re-ordering/sorting every row/column of a matrix with these operators
is generally faster than doing so through loops or apply-like functions.
Note that these operators strip all attributes except dimensions.
Examples
# numeric matrix ====
x <- matrix(sample(1:25), nrow = 5)
print(x)
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 9 10 3 16 11
#> [2,] 14 12 6 19 7
#> [3,] 5 15 20 21 22
#> [4,] 23 1 13 25 18
#> [5,] 2 4 24 17 8
x %row~% x # sort elements of every row independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 3 9 10 11 16
#> [2,] 6 7 12 14 19
#> [3,] 5 15 20 21 22
#> [4,] 1 13 18 23 25
#> [5,] 2 4 8 17 24
x %row~% -x # reverse-sort elements of every row independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 16 11 10 9 3
#> [2,] 19 14 12 7 6
#> [3,] 22 21 20 15 5
#> [4,] 25 23 18 13 1
#> [5,] 24 17 8 4 2
x %col~% x # sort elements of every column independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 2 1 3 16 7
#> [2,] 5 4 6 17 8
#> [3,] 9 10 13 19 11
#> [4,] 14 12 20 21 18
#> [5,] 23 15 24 25 22
x %col~% -x # reverse-sort elements of every column independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 23 15 24 25 22
#> [2,] 14 12 20 21 18
#> [3,] 9 10 13 19 11
#> [4,] 5 4 6 17 8
#> [5,] 2 1 3 16 7
x <- matrix(sample(1:25), nrow = 5)
print(x)
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 6 14 1 24 15
#> [2,] 7 2 3 11 4
#> [3,] 19 13 17 12 5
#> [4,] 10 20 8 22 23
#> [5,] 25 21 16 18 9
mat <- sample(seq_along(x)) |> matrix(ncol = ncol(x))
x %row~% mat # randomly shuffle every row independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 24 14 6 15
#> [2,] 11 4 3 2 7
#> [3,] 5 19 17 12 13
#> [4,] 20 22 8 23 10
#> [5,] 25 18 9 16 21
x %col~% mat # randomly shuffle every column independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 25 20 1 22 4
#> [2,] 19 2 3 11 5
#> [3,] 6 14 8 18 23
#> [4,] 10 21 17 24 9
#> [5,] 7 13 16 12 15
# character matrix ====
x <- matrix(sample(letters, 25), nrow = 5)
print(x)
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "g" "k" "t" "f" "y"
#> [2,] "s" "o" "z" "n" "u"
#> [3,] "b" "w" "h" "v" "i"
#> [4,] "j" "p" "e" "c" "d"
#> [5,] "a" "l" "q" "x" "r"
mat <- stringi::stri_rank(as.vector(x)) |> matrix(ncol = ncol(x))
x %row~% mat # sort elements of every row independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "f" "g" "k" "t" "y"
#> [2,] "n" "o" "s" "u" "z"
#> [3,] "b" "h" "i" "v" "w"
#> [4,] "c" "d" "e" "j" "p"
#> [5,] "a" "l" "q" "r" "x"
x %row~% -mat # reverse-sort elements of every row independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "y" "t" "k" "g" "f"
#> [2,] "z" "u" "s" "o" "n"
#> [3,] "w" "v" "i" "h" "b"
#> [4,] "p" "j" "e" "d" "c"
#> [5,] "x" "r" "q" "l" "a"
x %col~% mat # sort elements of every column independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "a" "k" "e" "c" "d"
#> [2,] "b" "l" "h" "f" "i"
#> [3,] "g" "o" "q" "n" "r"
#> [4,] "j" "p" "t" "v" "u"
#> [5,] "s" "w" "z" "x" "y"
x %col~% -mat # reverse-sort elements of every column independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "s" "w" "z" "x" "y"
#> [2,] "j" "p" "t" "v" "u"
#> [3,] "g" "o" "q" "n" "r"
#> [4,] "b" "l" "h" "f" "i"
#> [5,] "a" "k" "e" "c" "d"
x <- matrix(sample(letters, 25), nrow = 5)
print(x)
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "v" "n" "u" "w" "j"
#> [2,] "f" "q" "r" "b" "p"
#> [3,] "t" "c" "o" "h" "z"
#> [4,] "i" "s" "l" "y" "d"
#> [5,] "e" "g" "a" "m" "k"
mat <- sample(seq_along(x)) |> matrix(ncol = ncol(x))
x %row~% mat # randomly shuffle every row independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "j" "w" "u" "n" "v"
#> [2,] "q" "r" "p" "b" "f"
#> [3,] "c" "o" "h" "t" "z"
#> [4,] "y" "d" "l" "i" "s"
#> [5,] "g" "k" "a" "e" "m"
x %col~% mat # randomise shuffle every column independently
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "e" "g" "r" "y" "k"
#> [2,] "t" "c" "o" "w" "d"
#> [3,] "i" "q" "a" "h" "j"
#> [4,] "f" "s" "u" "m" "p"
#> [5,] "v" "n" "l" "b" "z"