17

I'm baffled as to why the boxplots are not ordering in this plot:

set.seed(200)
x <- data.frame(country=c(rep('UK', 10), 
                          rep("USA", 10), 
                          rep("Ireland", 5)),
                wing=c(rnorm(25)))

ggplot(x, aes(reorder(country, wing, median), wing)) + geom_boxplot()

enter image description here

How can I order the boxplots based on highest-lowest medians (left to right)?

luciano
  • 13,158
  • 36
  • 90
  • 130
  • 3
    Why did this get a down-vote? The question gives reproducible code and clearly shows effort. – Roland May 18 '13 at 10:24
  • It is not really reproducible. Missing the call to ggplot2. Also, your original figure does not match what I get. – user3236841 Mar 13 '18 at 21:41

3 Answers3

6

Because you did not make it an ordered factor. Try

ggplot(x, aes(reorder(country, wing, median, order=TRUE), wing)) + geom_boxplot()

enter image description here

Roland
  • 127,288
  • 10
  • 191
  • 288
  • 6
    including `order=TRUE` is giving the exactly the same plot for me – luciano May 18 '13 at 10:31
  • I added the result I get with the code. If you want descending order you need to use `function(x) -median(x)`. – Roland May 18 '13 at 10:41
  • 1
    I just experienced a similar problem and also clearing the workspace and restarting R produced the desired result. Also including `order=TRUE` is unnecessary. – David Lovell Sep 30 '13 at 09:50
  • (+1). Great advice about how to set in a decreasing order. I would suggest you to bring that to your answer. It took me a while to find this on SO. Tks. – Andre Silva Mar 16 '14 at 19:11
  • All factors have an order for the levels. The `order = TRUE` is not necessary. – Gregor Thomas Jun 28 '18 at 13:44
  • @Gregor I'm pretty sure I tested this when I wrote this answer and it was necessary (because ggplot2 created a new factor with standard alphabetical order). That might have changed but I can't test right now. – Roland Jun 30 '18 at 10:09
  • To my knowledge, it's never been necesary. `ggplot` won't create a new factor if it's already a factor - only if it is character. Older answers to similar questions, [such as this R-FAQ from 2011](https://stackoverflow.com/a/5210833/903061), don't specify `order = TRUE`. (And looking at the edit history, it never did.) – Gregor Thomas Jul 02 '18 at 01:47
  • @Gregor--reinstateMonica-- If `order = TRUE` is not necessary, what is the need of that argument? I've checked `is.ordered()` after reordering a factor and that shows as FALSE. – amsquareb Jan 04 '20 at 12:21
  • That's correct. All factors have an order to their levels--they have to, the levels are stored as a vector, and vectors have an order. If you use `order = TRUE`, then the class of the factor is `c("ordered", "factor")`. As the help page says, *"Ordered factors differ from factors only in their class, but methods and the model-fitting functions treat the two classes quite differently"*. – Gregor Thomas Jan 04 '20 at 22:01
  • @amsquareb The two most common places where these differences show up are (a) contrasts in models--by default regular `factor`s will use "treatment contrasts", the first level is a reference level and all other levels are compared to that. `ordered factor`s will default to polynomial contrasts. (e.g., `lm`, `glm`, really anything that uses `model.matrix` under the hood) (b) Comparison operations like `<`, `<=`, `min` and `max` have methods for ordered factors, but will throw an error for regular `factor`s. `ggplot2`, however, always has treated `factor`s and `ordered factor`s identically. – Gregor Thomas Jan 04 '20 at 22:06
1

Your code should works fine. Probably you had some package loaded with a function that masked the base reorder function, or perhaps a user-defined reorder function, that doesn't work the same way.

You can check for such name-clashes with conflicts(). Detaching the package, rm(reorder), or restarting R and trying again without defining/attaching the conflicting definition will solve the problem.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
-1
ggplot(x, aes(reorder(country, wing, FUN = median), wing)) + geom_boxplot()
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – Badacadabra Jun 15 '17 at 15:27