How to Sort a Matrix by All Columns

How to sort a matrix by all columns

This would work:

arr[do.call(order, lapply(1:NCOL(arr), function(i) arr[, i])), ]

What it is doing is:

arr[order(arr[, 1], arr[, 2], arr[ , 3]), ]

except it allows an arbitrary number of columns in the matrix.

How to sort a matrix/data.frame by all columns

Here's a concise solution:

mat[do.call(order,as.data.frame(mat)),];
## c b a
## [1,] 0 0 0
## [2,] 0 0 1
## [3,] 0 1 0
## [4,] 0 1 1
## [5,] 1 0 0
## [6,] 1 0 1
## [7,] 1 1 0
## [8,] 1 1 1

The call to as.data.frame() converts the matrix to a data.frame in the intuitive way, i.e. each matrix column becomes a list component in the new data.frame. From that, you can effectively pass each matrix column to a single invocation of order() by passing the listified form of the matrix as the second argument of do.call().

This will work for any number of columns.


It's not a dumb question. The reason that mat[order(as.data.frame(mat)),] does not work is because order() does not order data.frames by row.

Instead of returning a row order for the data.frame based on ordering the column vectors from left to right (which is what my solution does), it basically flattens the data.frame to a single big vector and orders that.

So, in fact, order(as.data.frame(mat)) is equivalent to order(mat), as a matrix is treated as a flat vector as well.

For your particular data, this returns 24 indexes, which could theoretically be used to index (as a vector) the original matrix mat, but since in the expression mat[order(as.data.frame(mat)),] you're trying to use them to index just the row dimension of mat, some of the indexes are past the highest row index, so you get a "subscript out of bounds" error.

See ?do.call.

I don't think I can explain it better than the help page; take a look at the examples, play with them until you get how it works. Basically, you need to call it when the arguments you want to pass to a single invocation of a function are trapped inside a list.

You can't pass the list itself (because then you're not passing the intended arguments, you're passing a list containing the intended arguments), so there must be a primitive function that "unwraps" the arguments from the list for the function call.

This is a common primitive in programming languages where functions are first-class objects, notably (besides R's do.call()) JavaScript's apply(), Python's (deprecated) apply(), and vim's call().

Sorting a matrix with order, using all columns, when you don't know the number of columns

Create string like A[,1],A[,2],A[,3],A[,4] in loop and next use parse and eval function to evaluate your expression.

set.seed(123)
A <- matrix(rep(1:25,4)[order(rnorm(100))],ncol=4)
col <- ""
for (i in 1:ncol(A)){
col <- paste(col,paste0('A[,',i,']'), sep = ",")
}
## remove first comma
col <- substr(col, 2, nchar(col))
col
[1] "A[,1],A[,2],A[,3],A[,4]"
B <- eval(parse(text = paste("A[order(",col,",decreasing=TRUE),]")))

Order a matrix by multiple column in r

The order function should do it.

df[order(df[,1],df[,2],decreasing=TRUE),]

How can I sort all columns of a matrix in javascript?

What you should do is flip the matrix so that all the rows are columns and all the columns are rows, using this zip function:

var zip = rows => rows[0].map((_,c) => rows.map(row=>row[c]));
var flipped = zip(matrix);

Then you can sort each row:

for (var i = 0; i < flipped.length; i++) {
flipped[i] = flipped[i].sort((a, b) => a - b);
}

Then flip it back:

var finalUnflippedResult = zip(flipped);

Putting it all together you get:

var zip = rows => rows[0].map((_,c) => rows.map(row=>row[c]));
var flipped = zip(matrix);
for (var i = 0; i < flipped.length; i++) {
flipped[i] = flipped[i].sort((a, b) => a - b);
}
var result = zip(flipped);

Order the entries including NA of all columns on a dataframe in R

Another way might be:

a <- c(5,1,0,3,2,0.6,1.6,7,9,0)
b <- c(11,0,1,18,11,11,0,13,20,10)
c <- c(10,20,0.7,0.8,0.3,0.4,0,0.9,1,1)
MAT <- cbind(a,b,c)

apply(`[<-`(row(MAT), MAT<=5, NA), 2, sort, na.last = TRUE)
# [,1] [,2] [,3]
# [1,] 8 1 1
# [2,] 9 4 2
# [3,] NA 5 NA
# [4,] NA 6 NA
# [5,] NA 8 NA
# [6,] NA 9 NA
# [7,] NA 10 NA
# [8,] NA NA NA
# [9,] NA NA NA
#[10,] NA NA NA

or

sapply(apply(MAT>5, 2, which, simplify = FALSE), `[`, 1:nrow(MAT))
# a b c
# [1,] 8 1 1
# [2,] 9 4 2
# [3,] NA 5 NA
# [4,] NA 6 NA
# [5,] NA 8 NA
# [6,] NA 9 NA
# [7,] NA 10 NA
# [8,] NA NA NA
# [9,] NA NA NA
#[10,] NA NA NA

Is there any way to sort columns of a matrix independently in R?

Yes, there is!

apply(mat, 2, sort)
[,1] [,2] [,3]
[1,] 1 1 2
[2,] 3 2 3
[3,] 34 5 4
[4,] 45 7 32
[5,] 4325 23 734

Sort matrix according to first column in R

Read the data:

foo <- read.table(text="1 349
1 393
1 392
4 459
3 49
3 32
2 94")

And sort:

foo[order(foo$V1),]

This relies on the fact that order keeps ties in their original order. See ?order.

Sort a matrix by last column

We order by the last column to get the expected output

m[order(m[,ncol(m)]),]
# [,1] [,2] [,3] [,4] [,5]
#[1,] 3 6 2 1 0
#[2,] 5 2 4 6 1
#[3,] 1 1 4 5 2
#[4,] 2 3 3 2 5

data

m <- structure(c(5L, 2L, 1L, 3L, 2L, 3L, 1L, 6L, 4L, 3L, 4L, 2L, 6L, 
2L, 5L, 1L, 1L, 5L, 2L, 0L), .Dim = 4:5)


Related Topics



Leave a reply



Submit