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: [EMAIL PROTECTED] on behalf of [EMAIL PROTECTED] Sent: Thu 7/31/2008 3:34 PM To: Johnson, Eric A. (Seattle) Cc: r-help@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: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] > On Behalf Of Timothy W. Hilton > Sent: Thursday, July 31, 2008 2:19 PM > To: r-help@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@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@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@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@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.