Reputation: 5059
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()
)
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
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())
Upvotes: 5