user3206440
user3206440

Reputation: 5059

ggplot - ordering bars in geom_bar facet_wrap

with a dataframe like below

set.seed(99)
data = data.frame(name=c("toyota", "nissan"), a=sample(1:10,2)/10,b=sample(-150:-50,2),c=sample(1e2:1e3,2),d=sample(1e3:1e5,2), e=sample(-15:30,2))

I'm trying to plot the various variables onto a single chart as below. This works well

library(ggplot2)
library(reshape2)
ggplot(melt(data, id = "name")) + 
  aes(name, value, fill = name) + 
  geom_col(position = "dodge") +
  facet_wrap(~ variable, scales = "free_y") +
  theme(
    axis.text.x=element_blank(),
    axis.text.y=element_blank()
    )

enter image description here

The issue I have is that I want the bars in each facet to be ordered with highest values first - how do I go about this ? Note that I still need to keep the order in legend as it is - that is nissan, toyota

Upvotes: 2

Views: 2067

Answers (1)

jazzurro
jazzurro

Reputation: 23574

I came up with the following idea after reading Mr. Flick's answer in this question. I would like to give him credit.

What Mr. Flick did in the question is to create a new factor variable. Right now you have Nissan and Toyota. But we want to assign a unique factor level for each of Nissan and Toyota; we want to create ten levels. We want to find the proper order for each of the car company in each level of variable. The outcome of this process is stored as foo. In the next step, we want to create a new factor variable, which is identical to foo in mutate() in the previous code. Then, assign levels using foo. In the code for ggplot, we want to use scales = "free".

library(reshape2)
library(dplyr)
library(ggplot2)

temp <- melt(data, id = "name")

# Deciding the level order

foo <- temp %>%
       group_by(variable) %>%
       mutate(foo = levels(reorder(factor(paste(name, variable, sep = ".")), -value))) %>%
       pull(foo)

# Creating a new factor variable and assign levels with foo.

out <- temp %>% 
       mutate(new = factor(interaction(name, variable), levels = foo))

ggplot(data = out, aes(x = new, y = value, fill = name)) +
geom_col(position = "dodge") +
facet_wrap(~ variable, scales = "free") +
labs(x = "", fill = "Car company") +
theme(axis.text.x = element_blank(),
      axis.text.y = element_blank()) 

enter image description here

Upvotes: 5

Related Questions