15

I'm trying to reorder the rows of a data frame by two factors. For the first factor i'm happy with the default ordering. For the second factor i'd like to impose my own custom order to the rows. Here's some dummy data:

dat <- data.frame(apple=rep(LETTERS[1:10], 3), 
                  orange=c(rep("agg", 10), rep("org", 10), rep("fut", 10)),
                  pear=rnorm(30, 10), 
                  grape=rnorm(30, 10))

I'd like to order "apple" in a specific way:

appleOrdered <- c("E", "D", "J", "A", "F", "G", "I", "B", "H", "C")

I've tried this:

dat <- dat[with(dat, order(orange, rep(appleOrdered, 3))), ]

But it seems to put "apple" into a random order. Any suggestions? Thanks.

Steve
  • 5,727
  • 10
  • 32
  • 30
  • Related to [How do I sort one vector based on values of another](http://stackoverflow.com/questions/1568511/how-do-i-sort-one-vector-based-on-values-of-another) – Joshua Ulrich Jul 20 '11 at 23:46

2 Answers2

12

Try using a factor with the levels in the desired order and the arrange function from plyr:

dat$apple <- factor(dat$apple,levels=appleOrdered)
arrange(dat,orange,apple)
joran
  • 169,992
  • 32
  • 429
  • 468
12

Reordering the factor levels:

dat[with(dat, order(orange, as.integer(factor(apple, appleOrdered)))), ]
Charles
  • 4,389
  • 2
  • 16
  • 13
  • 1
    This works great, thanks. Is there any reason to wrap the factor call in as.integer()? Removing it seems to give exactly the same result. – Steve Jul 21 '11 at 05:01
  • Sounds find - I wasn't positive if factor sort order was defined by the levels or the as.character() of it. – Charles Jul 21 '11 at 13:07