[R] sort rows of matrix by rows of another matrix

Steven McKinney smckinney at bccrc.ca
Fri Aug 1 03:17:53 CEST 2008


I came up with the same solution as Mark Leeds.

> a1roworders <- t(apply(a1, 1, order))
> a2ord <- t(sapply(seq(nrow(a1)), function(x) a2[x, a1roworders[x,]] ))
> a2ord
     [,1] [,2] [,3]
[1,]  102  101  103
[2,]  102  101  103
[3,]  103  101  102
[4,]  101  102  103

Mark's question about the orientation of
apply() output is common, and a source of
confusion for many who are used to matrix
results that just show up in the right orientation
from most other S-language function output.

The help page for apply() states
 "If each call to FUN returns a vector of length n, 
  then apply returns an array of dimension 
  c(n, dim(X)[MARGIN]) if n > 1."

So, whenever you use apply() on
margin 1 (the rows) and your function
returns a result for each column, each
call to FUN returns a vector of length
n = ncol(X), and this dimension becomes
the row dimension of the result (i.e.
column dimensions and row dimensions
appear mysteriously switched).

Since apply() can be used on multiple
margins of arrays with many margins, 
some standard output format had to be
set up, and the format is stated
above.  

So this is just one of those bits of
S language trivia that you have to file
away in the grey matter - since apply()
can be used on arbitrary arrays, it has
to have a standard output format, and
that standard appears to transpose your
result matrix when you do column-wise
stuff to the rows of your two-dimensional
matrix.

The old Blue Book ("The New S Language")
showed examples

 apply(x, 2, sort) # sort columns of x
 t(apply(x, 1, sort)) # transpose result of row sort

and commented

 "The sorting examples show the difference between row and
  column operations when the results returned by FUN are vectors.
  The returned value becomes the <first> dimension of the result,
  hence the transpose is necessary with row sorts."

This was a useful comment and pointed this issue
out plainly.  I'd vote for this set of examples
to be in R's help page for apply(), with the comment
as well, e.g. 

 apply(x, 2, sort) # sort columns of x
 t(apply(x, 1, sort)) # transpose result of row sort

## The sorting examples show the difference between row and
## column operations when the results returned by FUN are vectors.
## The returned value becomes the <first> dimension of the result,
## hence the transpose is necessary with row sorts."

would be useful examples and comments for R's apply()
help page.

HTH

Steve McKinney





-----Original Message-----
From: r-help-bounces at r-project.org on behalf of markleeds at verizon.net
Sent: Thu 7/31/2008 3:34 PM
To: Johnson, Eric A. (Seattle)
Cc: r-help at r-project.org
Subject: Re: [R] sort rows of matrix by rows of another matrix
 
below is another way ( maybe the same ?  )but with an extra line to make 
roworder. i'm also not clear on why I  have to take the transpose of 
the result that
comes back form the apply call. in ?apply, it says that the function 
tries to convert the result back to a matrix. that's fine but why does 
it do
it in the opposite way from the way the data in sent in ( i.e : by row 
). if someone could explain that, i'd appreciate it.


a1 <- structure(c(7, 4, 4, 0, 6, 2, 7, 3, 8, 4, 2, 8), .Dim = c(4L, 3L))
a2 <- structure(c(101L, 101L, 101L, 101L, 102L, 102L, 102L, 102L, 103L,
103L, 103L, 103L), .Dim = c(4L, 3L))

roworder <- t(apply(a1,1,order))

a3 <- t(sapply(1:nrow(a2),function(.rowind) {
   a2[.rowind,roworder[.rowind,]]
}))

print(a3)



On Thu, Jul 31, 2008 at  6:05 PM, Johnson, Eric A. (Seattle) wrote:

> If you're not adverse to cbind-ing a1 and a2, you can use this:
>
> a1a2 <- cbind(a1, a2)
>
> a3 <- t(apply(a1a2, 1, function(x) x[order(x[1:ncol(a1)])+ncol(a1)]))
>
> Eric
>
>
> -----Original Message-----
> From: r-help-bounces at r-project.org 
> [mailto:r-help-bounces at r-project.org]
> On Behalf Of Timothy W. Hilton
> Sent: Thursday, July 31, 2008 2:19 PM
> To: r-help at r-project.org
> Subject: [R] sort rows of matrix by rows of another matrix
>
> Hello all,
>
> I am trying to sort rows of one matrix by rows of another.  Given a1 
> and
> a2:
>
> ------
>> a1
>      [,1] [,2] [,3]
> [1,]    7    6    8
> [2,]    4    2    4
> [3,]    4    7    2
> [4,]    0    3    8
>
> a1 <-
> structure(c(7, 4, 4, 0, 6, 2, 7, 3, 8, 4, 2, 8), .Dim = c(4L, 3L))
>
>> a2
>      [,1] [,2] [,3]
> [1,]  101  102  103
> [2,]  101  102  103
> [3,]  101  102  103
> [4,]  101  102  103
>
> a2 <-
> structure(c(101L, 101L, 101L, 101L, 102L, 102L, 102L, 102L, 103L, 
> 103L, 103L, 103L), .Dim = c(4L, 3L))
> ------
>
> I want to get a3:
>
>> a3
>      [,1] [,2] [,3]
> [1,]  102  101  103
> [2,]  102  101  103
> [3,]  103  101  102
> [4,]  101  102  103
>
> where the rows of a3 are the rows of a2 sorted according to the rows 
> of
> a1.
>
> I can get the necessary sorting index:
>> apply(a1, 1, order)
>      [,1] [,2] [,3] [,4]
> [1,]    2    2    3    1
> [2,]    1    1    1    2
> [3,]    3    3    2    3
>
> and I can get the rows of a1 sorted according to the rows of a1:
>> t(apply(a1, 1, function(x) x[order(x)]))
>      [,1] [,2] [,3]
> [1,]    6    7    8
> [2,]    2    4    4
> [3,]    2    4    7
> [4,]    0    3    8
>
> but I can't get the rows of a2 sorted according to the rows of a1...
>
> Thanks,
> Tim
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide 
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
R-help at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list