tjnel
tjnel

Reputation: 683

Order data frame by columns in increasing and decreasing order

I'm trying to figure out how to sort a data frame like the one below by c1 in decreasing order and c2 in increasing order.

c1 <- c("a", "b", "c", "d", "d", "e", "f", "g", "h", "i")
c2 <- c("29-JAN-08", "29-JAN-08", "29-JAN-08", "29-JAN-08", "20-MAR-08", "28-MAR-08", "28-MAR-08", "28-MAR-08", "28-MAR-08", "28-MAR-08")
example <- data.frame(c1, c2)

I can't use the - sign with a date vector:

> example <- example[order(example$c1, -example$c2),]
Error: unexpected input in "example <- example[order(example$c1, -1ex"

And I haven't been able to figure out how to use the 'decreasing' argument:

> example <- example[order(example$c1, example$c2, decreasing = c(F, T)),]
Error: unexpected input in "example <- example[order(example$c1, -1ex"

Is there a way I can order this data frame by these two columns, in increasing order by the first one and decreasing order by the second when the columns are character and date types, respectively?

Upvotes: 3

Views: 7281

Answers (2)

thelatemail
thelatemail

Reputation: 93813

Here's an answer using the data.table package, which shows off it's benefits in terms of cleaner code:

example <- as.data.table(example)
# set the date variable as an actual date first
example$c2 <- as.Date(example$c2,format="%d-%b-%Y")

# then sort - notice no need to keep referencing example$...
example[order(c1,-as.numeric(c2))]

A base R version of how to do this would use with

example[with(example,order(c1,-as.numeric(c2))),]

Upvotes: 4

IRTFM
IRTFM

Reputation: 263342

This would do the reverse lexical sort, but it may not be what you were intending since you have not yet converted to Date values, since the reverse sorting will first be be done on the character day "field":

 example[ order(example$c1, rev(example$c2)) , ]
#-------
   c1        c2
1   a 29-JAN-08
2   b 29-JAN-08
3   c 29-JAN-08
4   d 29-JAN-08
5   d 20-MAR-08
6   e 28-MAR-08
7   f 28-MAR-08
8   g 28-MAR-08
9   h 28-MAR-08
10  i 28-MAR-08

If you want to do the sort in reverse "true" date-order:

example[ order(example$c1, -as.numeric(as.Date(example$c2, format="%d-%b-%Y"))) , ]
#-----
   c1        c2
1   a 29-JAN-08
2   b 29-JAN-08
3   c 29-JAN-08
5   d 20-MAR-08
4   d 29-JAN-08
6   e 28-MAR-08
7   f 28-MAR-08
8   g 28-MAR-08
9   h 28-MAR-08
10  i 28-MAR-08
9   h 28-MAR-08
10  i 28-MAR-08

Upvotes: 3

Related Questions