32

This question follows from this other one. I was unable to implement answers there.

Define:

df2 <- data.frame(variable=rep(c("vnu.shr","vph.shr"),each=10),
        value=seq(1:20))

Plot:

require(ggplot2)
qplot(variable,value, data=df2,geom="boxplot")+
geom_jitter(position=position_jitter(w=0.1,h=0.1))

I would like to have the boxplots in the reverse order (e.g. one in right on left and so on).

I have tried various ways of reordering the factors using levels, ordered, relevel, rev and so on, but I simply cannot seem to get the syntax right.

Community
  • 1
  • 1
Fred
  • 1,833
  • 3
  • 24
  • 29
  • This has been dealt with on SO a number of times. Here are just two top examples: http://stackoverflow.com/questions/3253641/how-to-change-the-order-of-a-discrete-x-scale-in-ggplot http://stackoverflow.com/questions/5967593/ordering-of-bars-in-ggplot – Roman Luštrik Jul 29 '11 at 07:34
  • @ Roman Luštrik Which perhaps goes to show how confusing reordering factors can be to the uninitiated. I for one, had tried to sort the data frame so that the factor was in reverse alphabetical order, and then recode it as factor. That does not work bc for factor `z=c("b","a")` the underlying numbers applied by `R` follow alphabetic order (which makes sense) s.t. the numeric coding is `z=c(2,1)`. But, now I know, reordering a factor has nothing to do with reordering the dataframe! When reordering the factor we are not reordering the data but changing underlying numbers to `z=c(1,2)` say. – Fred Jul 29 '11 at 15:06
  • For plotting purposes, it's the order of levels of a factor that define the ordering in the plot. Once you get that under your skin, it's a smooth ride. Regarding confusion about reordering... Have you ever tried outputting a lattice/ggplot plot to a pdf? :) Boy, before you realize that it's not your code but a missing `print` statement... – Roman Luštrik Jul 29 '11 at 15:54
  • 1
    @Roman Luštrik Re. PDF you might want to check `ggsave` [here](http://stackoverflow.com/questions/5625394/problem-saving-pdf-file-in-r-with-ggplot2) – Fred Jul 29 '11 at 17:02

2 Answers2

60

Have you tried this:

df2$variable <- factor(df2$variable,
    levels = c('vph.shr','vnu.shr'),ordered = TRUE)

I just picked an ordering there, since my system is configured slightly differently than yours I suspect, so my 'default ordering' may differ. But you can just switch the position of levels when specifying them.

A few other options, depend on your tastes:

For just reversing the current ordering:

factor(df2$variable,levels = rev(levels(df2$variable)),ordered = TRUE)

or you can use subsetting to specify a specific ordering if you don't want to type out each level by hand:

factor(df2$variable,levels = levels(df2$variable)[1:2],ordered = TRUE)
joran
  • 169,992
  • 32
  • 429
  • 468
  • i have used your solution in the past and it's worked, but I am using it now (have tested all of the above) on a violin + boxplot and it doesn't want to change. Any ideas of what it could be? – stevec May 09 '20 at 18:10
9

You've already accepted a (perfectly fine) solution, but here's another option using relevel(). I'm not sure why it wasn't working for you?

#default plot
ggplot(df2, aes(variable, value)) + geom_boxplot()

enter image description here

#Reverse reverse!
df2$variable2 <- with(df2, relevel(variable, "vph.shr"))
ggplot(df2, aes(variable2, value)) + geom_boxplot()

enter image description here

Chase
  • 67,710
  • 18
  • 144
  • 161
  • 13
    Whats up with the pictures? Where u using a Commodore 64 or some other 1980s device? ;-) – Fred Jul 29 '11 at 15:10
  • 9
    @Fred - I drew them by hand in microsoft paint to look like the output from a ggplot device. Actually, I saved the images as small jpegs (2 x 2) so they wouldn't be distracting...but wherever SO hosts the images has it's own ideas about how large the pictures should be... – Chase Jul 29 '11 at 15:21
  • 2
    I love the [evil pixel](http://www.youtube.com/watch?v=iBGZPzt5Dts) aesthetic. Nice to know how to replicate it. – Fred Jul 29 '11 at 15:29