2

I have data similar to these:

data <- data.frame(x1=rexp(10,2),y1=rnorm(10,1),x2=rexp(10,2),y2=rnorm(10,1),x3=rexp(10,2),y3=rnorm(10,1),x4=rexp(10,2),y4=rnorm(10,1)) 

I would like to order all y1,y2... variables in increasing order.

I have tried this among others:

data[with(data,order(y1,y2,y3,y4,decreasing=FALSE)), ] 

There is number of SO contribution for example here about order, yet I cannot make it work.

6
  • What is the problem with the one in the link? Commented Jan 19, 2015 at 14:21
  • Only the first column y1 is order not the rest y2... Commented Jan 19, 2015 at 14:26
  • Should the order of the values in the x columns change too? Commented Jan 19, 2015 at 14:30
  • 1
    I think you could use do.call(order, c(data[grep('^y', names(data))], decreasing=TRUE) Commented Jan 19, 2015 at 14:31
  • @akrun: I like your solution, if you would submit it, I would accept it. Thanks. Commented Jan 19, 2015 at 14:35

3 Answers 3

4

You could try

indx <- do.call(order, c(data[grep('^y', names(data))], decreasing=TRUE)) data[indx,] 

By default, the option is decreasing=FALSE. If that is what you wanted, just do

indx <- do.call(order, data[grep('^y', names(data))]) 
Sign up to request clarification or add additional context in comments.

Comments

3

With data.table package you can either sort by reference and pass several variable names at once to the setorder function (this function isn't mentioned in the above link)

library(data.table) setorderv(setDT(data), grep("^y\\d+", names(data), value = TRUE)) 

If you want decreasind order you can specify the order, e.g.,

setorderv(setDT(data), grep("^y\\d+", names(data), value = TRUE), order = -1L) 

The nicest thing about it, is that you can pass a whole vector into order that will sort each column differently, for example

indx <- c(1L, -1L, -1L, 1L) setorderv(setDT(data), grep("^y\\d+", names(data), value = TRUE), order = indx) 

While everything is done by reference (without creating copies using <-)

5 Comments

How do you change the order to decreasing=TRUE here?
That is very informative. Will definitely steal these ideas :-)
@akrun It is pitty @Matt didn't add this to his data.table answer in the link mentioned by the OP
You could update in that link or post as a new solution there.
This is very handy. I decided to accept David your solution as in my opinion is marginally better and possibly usefully to others. Thanks!
0

I think the cited solution does exactly what it is supposed to do - sort first on y1, then (for same y1-values) on y2, and so on.

If you want to have each x-y pairs sorted independently, you have to break up the data.frame.

data.frame(data[with(data,order(y1,decreasing=FALSE)),c('x1', 'y1') ], data[with(data,order(y2,decreasing=FALSE)),c('x2', 'y2') ], data[with(data,order(y3,decreasing=FALSE)),c('x3', 'y3') ], data[with(data,order(y4,decreasing=FALSE)),c('x4', 'y4') ]) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.