Superficial
Superficial

Reputation: 23

Unexpected behaviour when re-ordering facets (for ggplot2)

I'd like some help understanding an error so that it can't happen again.

I was producing some (gg) plots and wanted to change the order of facets for aesthetic reasons. The way I did this had unexpected consequences and almost slipped through the net when I was checking the results - it could have caused serious problems with the article I'm working on!

I wanted to re-order the facets based on a numerical vector that I could define up-front E.g. facet_order=c(1,2,4,3). This was so the graph syntax could be copied / pasted for repeat graphs more easily and I wouldn't have to dig around too much in the code each time.


# some example data:
df <- data.frame(x=c(1,2,3,4), y=c(1,2,3,4), facet_var=factor(c('A','B','C','D')))

# First plot (facet order defined by default):
ggplot(df, aes(x,y))+geom_point()+facet_wrap(~facet_var, nrow = 1)+labs(title='Original data')

In the second plot, facets 'C' and 'D' are swapped as intended:


# reorder facets (normal method)
df$facet_var2 <- factor(df$facet_var, levels=c('A','B','D','C')) # Set the facets var 
as a factor, to define the order

# Second plot:
ggplot(df, aes(x,y))+geom_point()+facet_wrap(~facet_var2, nrow = 1)+labs(title='Re- 
ordered facets', subtitle='working as expected')

However, this is the mistake I made:


# different syntax to reorder the facets
df$facet_var3 <- df$facet_var # duplicate the faceting variable
levels(df$facet_var3) <- levels(df$facet_var3)[c(1,2,4,3)]  # I thought I was just 
re-ordering the levels here

# Third plot:
ggplot(df, aes(x,y))+geom_point()+facet_wrap(~facet_var3, nrow = 1)+labs(title='Re- 
ordered facets (method 2)',subtitle='Unexpected behaviour')

In the third graph, it looks like the data doesn't move, but the facet labels do, which is obviously wrong.

Digging a bit deeper, it appears that my syntax changed not only the order of the factor, but actually the underlying data in the factor variable. Is this behaviour expected?

Here's the crux of it:


facet_order <- c(1,2,4,3)

levels(df$facet_var) <- levels(df$facet_var)[facet_order]  # bad
df$facet_var <- factor(df$facet_var, levels=c(levels(df$facet_var)[facet_order)) # 
good

Obviously I now know the solution but I'm still unclear what I actually did wrong here. Any pointers?

Hang on while I try and fix the images:

a busy cat

a busy cat

a busy cat

Upvotes: 0

Views: 198

Answers (1)

user18309711
user18309711

Reputation:

quick'n'dirty: posterior reordering with fct_reorder of {forcats} (part of tidyverse):

ggplot(df, aes(x,y)) +
    geom_point() +
    facet_wrap(~ fct_reorder(facet_var, c('B','A','D','C')),
               nrow = 1)

Upvotes: 2

Related Questions