Reputation: 287
I have a dataframe
df <- data.frame(respondent = factor(c(1, 2, 3, 4, 5, 6, 7)),
location = factor(c("US: California", "US: Oregon", "Mexico",
"US: Texas", "Canada", "Mexico", "Canada")))
There are three separate levels related to the US. I don't want to collapse them as the distinction between states is useful for data analysis. I would like to have, however, a basic barplot that stacks the US states on top of one another, so that there are three bars in the barplot--Canada, Mexico, and US--with the last one divided into three states, instead of this:
ggplot(df, aes(location, 1))+
geom_bar(stat = "identity")+
theme(axis.text.x = element_text(angle = 45, hjust = 1),
text = element_text(size=10))
which gives me five bars, with three for the US.
There is an old similar question on Stackoverflow (Grouping/stacking factor levels in ggplot bar chart), but the solution given is pretty convoluted. I'm hoping that there is an easier way to achieve this. Any ideas how it can be done?
Upvotes: 1
Views: 769
Reputation: 16832
tidyverse
solution: Use separate
from tidyr
to split the locations by :
into two columns, one for country and one for state. Locations that don't have a colon separator will get NA
for state, which you can replace with something like "Outside US".
I moved this non-US level to the end so it would show up last on the legend, but this might not be necessary for your purposes. Then set the fill based on the state, so you can see the US values stack up by state.
You might also want to set a scale that gives the non-US values a muted or gray color to contrast with the stacked ones, but I'll leave the design concerns up to you.
library(tidyverse)
df <- data.frame(respondent = factor(c(1, 2, 3, 4, 5, 6, 7)), location = factor(c("US: California", "US: Oregon", "Mexico", "US: Texas", "Canada", "Mexico", "Canada")))
with_states <- df %>%
separate(location, into = c("Country", "State"), sep = ": ") %>%
replace_na(list(State = "Outside US")) %>%
mutate(State = as.factor(State) %>% fct_relevel("Outside US", after = Inf))
ggplot(with_states, aes(x = Country, y = 1, fill = State)) +
geom_col()
Created on 2018-05-24 by the reprex package (v0.2.0).
Upvotes: 4