Maximilian
Maximilian

Reputation: 4229

Order dataframe for given columns

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.

Upvotes: 2

Views: 149

Answers (3)

David Arenburg
David Arenburg

Reputation: 92282

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 <-)

Upvotes: 3

akrun
akrun

Reputation: 886938

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))])

Upvotes: 4

Julian
Julian

Reputation: 791

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') ])

Upvotes: 0

Related Questions