title: R: ordering facets by value rather than alphabetical order in a ggplot2 plot
body: <p>A couple of weeks ago I used ggplot2 to create a faceted plot where the facets were ordered by the last value in the data frame. I had no major problems until it came to reordering, as I haven't really assimilated all the complications of orders, factors and levels. Still, after an hour or two (or three) of referring to SO posts I got it working.</p>
  
  <p>When I came back to the script today it was no longer "working" in that it is now sorting the facets by alphabetical order rather than by the final value of the data frame. (I think that I originally "fixed" the problem while messing around at the R console and did not actually add the solution to the script.) Rather than spending another couple of hours on this tonight I'm going to throw myself on the mercy of SO.</p>
  
  <p>Q. How can I sort the facets by a specified value rather than by the alphabetical order of the names of each facet? Please note the following code is an example only; the real data has several dozen items.</p>
  
  <p>Edited code below to reflect additional input from @joran; the facets are now sorted and filled appropriately. Mission successful.</p>
  
  <pre><code># Version 3
  require(ggplot2) ## NB This script assumes you have ggplot2 v0.90
  require(scales)
  require(plyr)
  require(lubridate)
  require(reshape)
  
  set.seed(12345)
  monthsback &lt;- 15
  date &lt;- as.Date(paste(year(now()),month(now()),"1",sep="-")) - months(monthsback)
  myitems &lt;- data.frame(mydate=seq(as.Date(date), by="month", length.out=monthsback),
                        aaa = runif(monthsback, min = 600, max = 800),
                        bbb = runif(monthsback, min = 100, max = 200),
                        ccc = runif(monthsback, min = 1400, max = 2000),
                        ddd = runif(monthsback, min = 50, max = 120))
  
  myitems &lt;- melt(myitems, id = c('mydate'))
  
  change_from_start &lt;- function(x) {
     (x - x[1]) / x[1]
  }
  
  myitems &lt;- ddply(myitems, .(variable), transform, value = change_from_start(value))
  myitems$mydate &lt;- as.Date(myitems$mydate, format = "%Y-%m-%d")
  myvals &lt;- myitems[myitems$mydate == myitems$mydate[nrow(myitems)],] # get values on which to sort facets
  myvals &lt;- within(myvals, variable &lt;- factor(variable, as.character(myvals[order(myvals$value, decreasing = T),]$variable),ordered = TRUE))
  myitems &lt;- within(myitems, variable &lt;- factor(variable, as.character(myvals[order(myvals$value, decreasing = T),]$variable),ordered = TRUE))
  print(levels(myitems$variable)) # check to see if ordering succeeded
  myitems$fill &lt;- ifelse(myitems$variable == "ddd", "blue", "darkgreen")
  
      p &lt;- ggplot(myitems, aes(y = value, x = mydate, group = variable)) +
        geom_rect(aes(xmin = as.Date(myitems$mydate[1]), xmax = Inf, fill = fill), ymin = -Inf, ymax = Inf) +
        scale_fill_manual(values = c("blue", "darkgreen")) +
        geom_line(colour = "black") +
        geom_text(data = myvals, aes(x = as.Date(myitems$mydate[1]) + 250, y = 0.2, label = sprintf("%1.1f%%", value * 100))) +
        facet_wrap( ~ variable, ncol = 2) +
        geom_hline(yintercept = 0, size = 0.6, linetype = "dotdash") +
        scale_y_continuous(label = percent_format()) +
        scale_x_date(expand = c(0,0), labels = date_format("%Y-%m"), breaks = date_breaks("year")) +
        xlab(NULL) +
        ylab(NULL) +
        opts(legend.position = "none") +
        opts(panel.grid.minor = theme_blank()) +
        opts()
  
  print(p)
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/fnPdw.png" alt="Image showing that facets are now sorted properly but that the fill is no longer working"></p>