library(tidyverse)
library(ggsci)
DF <- tibble(Decision = sample(c("Negative","Positive"), 500, T),
Category1 = sample(c("X", "Y", "Z"), 500, T),
Category2 = sample(c("Yellow", "Blue", "Black", "White"), 500, T),
Category3 = sample(c("Xyz", "Yes", "Zos"), 500, T),
Category4 = sample(c("O", "F"), 500, T),
Category5 = sample(c("Xxx", "Yyy", "Zzz", "ooo", "Aha!"), 500, T))
I have a dataset with five different questions, each with a unique set of answers. Each person who answered these five questions ended with either a positive or negative decision (the 6th variable). I created a bar plot which shows the percent of positive decisions separately for each answer to each question using the code below:
DF %>% pivot_longer(cols = 2:6, values_to = "Answer", names_to = "Category") %>%
count(Category, Decision, Answer) %>%
group_by(Category, Answer) %>% mutate(percent = n / sum(n) * 100) %>%
filter(Decision == "Positive") %>%
ggplot(aes(Answer %>% fct_reorder2(percent, Category), percent, fill = Category)) +
geom_bar(stat = "identity", position = position_dodge(), width = 0.95, color = "black", alpha = 0.5) + coord_flip() +
scale_fill_uchicago() + labs(x = "", y = "", fill = "") + scale_y_continuous(breaks = seq(0, 100, 20), labels = str_c(seq(0, 100, 20), "%")) +
theme_classic() + theme(legend.position = "top")
My question is - is there anyway to bring some space between the sets of answers to each of the questions? I would like the columns of the same color to be next to each other, but at the same time, I would like to add some space between columns of different color, as to make it more clear visually that those are 5 different variables.
Additionally, if it is possible, I would like to present the columns in a descending order separately for each category. Unfortunately, adding width to position_dodge
position_dodge(0.5)
does not work, which I guess makes sense.
I will be grateful for any help. Thank you in advance!
This could be achieved like so:
To add some space between categories you could make use of facet_grid
, get rid of the strip texts and set the panel spacing to zero. Additionally I make use of space="free"
so that you bars still have the same width.
To reorder your bars in descending order you could make use of tidytext:: reorder_within
and tidytext::scale_x_reordered()
library(tidyverse)
library(ggsci)
library(tidytext)
set.seed(42)
DF <- tibble(
Decision = sample(c("Negative", "Positive"), 500, T),
Category1 = sample(c("X", "Y", "Z"), 500, T),
Category2 = sample(c("Yellow", "Blue", "Black", "White"), 500, T),
Category3 = sample(c("Xyz", "Yes", "Zos"), 500, T),
Category4 = sample(c("O", "F"), 500, T),
Category5 = sample(c("Xxx", "Yyy", "Zzz", "ooo", "Aha!"), 500, T)
)
DF %>%
pivot_longer(cols = 2:6, values_to = "Answer", names_to = "Category") %>%
count(Category, Decision, Answer) %>%
group_by(Category, Answer) %>%
mutate(percent = n / sum(n) * 100) %>%
filter(Decision == "Positive") %>%
ungroup() %>%
mutate(Answer = tidytext::reorder_within(Answer, by = percent, within = Category)) %>%
ggplot(aes(Answer, percent, fill = Category)) +
geom_bar(stat = "identity", position = position_dodge(), width = 0.9, color = "black", alpha = 0.5) +
coord_flip() +
scale_fill_uchicago() +
labs(x = "", y = "", fill = "") +
scale_y_continuous(breaks = seq(0, 100, 20), labels = str_c(seq(0, 100, 20), "%")) +
tidytext::scale_x_reordered() +
facet_grid(Category ~ ., scales = "free_y", space = "free") +
theme_classic() +
theme(legend.position = "top", strip.text = element_blank(), panel.spacing.y = unit(0, "pt"))