Reputation: 995
my intention is to plot 2 charts "long term" and "very long term" unemployment using ggplot2 and facet_wrap. I would like the order to be ascending by indic=="LTU" (top part of facet_wrap), so in the top chart "LU" and "MT" would not be on the right side. But I don't manage ggplot to order the bars properly. Any advice?
Reproducible example:
library(tidyverse)
library(eurostat)
#Long-term unemployment by sex - quarterly average
une_ltu_q <- get_eurostat("une_ltu_q", stringsAsFactors=FALSE)
df <- une_ltu_q %>% filter(age=="Y15-74",
geo %in% c("EU28", "BE","BG","CZ","DK","DE","EE","IE","EL","ES","FR","HR","IT","CY","LV","LT","LU","HU","MT","NL","AT","PL","PT","RO","SI","SK","FI","SE","UK"),
sex=="T",
s_adj=="SA",
time==max(une_ltu_q$time),
unit=="PC_ACT")%>%
group_by(indic_em)%>% arrange()
ggplot(data=df, aes(x=reorder(geo, values), y=values))+
geom_bar(stat = "identity",
position = "dodge",
show.legend = FALSE,
fill="steelblue")+
geom_text(aes(label=values), vjust=-0.5, size=3.5)+
facet_wrap(~indic_em, ncol=1, scales = "free")
Upvotes: 3
Views: 739
Reputation: 66
Using the codes found at: https://github.com/dgrtwo/drlib/blob/master/R/reorder_within.R
We can use these functions to reorder within groups so each facet will have ascending bars. Below is the modified ggplot code integrating these functions.
reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
new_x <- paste(x, within, sep = sep)
stats::reorder(new_x, by, FUN = fun)
}
scale_x_reordered <- function(..., sep = "___") {
reg <- paste0(sep, ".+$")
ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}
ggplot(data=df, aes(x=reorder_within(geo, values, indic_em), y=values))+
geom_col(stat = "identity",
position = "dodge",
show.legend = FALSE,
fill="steelblue")+
geom_text(aes(label=values), vjust=-0.5, size=3.5)+
scale_x_reordered()+
facet_wrap(~indic_em, ncol=1, scales = "free")
Upvotes: 1
Reputation: 54237
reorder
has a FUN
ction argument, which you can use to change the ordering. By default, your example is ordered by the mean
of the two values. But you could also take just the first value:
ggplot(data=df, aes(x=reorder(geo, values, "[", 1), y=values))+
geom_bar(stat = "identity",
position = "dodge",
show.legend = FALSE,
fill="steelblue")+
geom_text(aes(label=values), vjust=-0.5, size=3.5)+
facet_wrap(~indic_em, ncol=1, scales = "free")
or the sum
:
ggplot(data=df, aes(x=reorder(geo, values, sum, na.rm=T), y=values))+
geom_bar(stat = "identity",
position = "dodge",
show.legend = FALSE,
fill="steelblue")+
geom_text(aes(label=values), vjust=-0.5, size=3.5)+
facet_wrap(~indic_em, ncol=1, scales = "free")
Upvotes: 2