I'm using the excellent package ggrepel() to position text labels on bars with a bit of jitter. The only trouble is that they are appearing in reverse order. Here's some reproducible code:
library(tidyverse)
require(scales) # Used for adding percentages to bar charts
library(ggrepel)
# ingest some sample data
structure(list(Q52_bin = structure(c(3L, 2L, 2L, 2L, 2L, 2L,
2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 2L, 2L, 1L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 2L, 1L, 2L,
2L, 1L, 3L, 2L, 3L, 3L, 1L), .Label = c("low", "medium", "high"
), class = "factor"), Q53_bin = structure(c(2L, 3L, 2L, 2L, 2L,
2L, 2L, 3L, 2L, 3L, 2L, 1L, 2L, 2L, 1L, 2L, 3L, 2L, 2L, 1L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 3L, 1L,
2L, 2L, 2L, 1L, 2L, 2L, 3L, 2L), .Label = c("low", "medium",
"high"), class = "factor"), Q57_bin = structure(c(2L, 2L, 2L,
2L, 2L, 2L, 2L, 1L, 1L, 1L, 3L, 2L, 2L, 2L, 2L, 2L, 3L, 2L, 1L,
1L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 1L, 3L,
3L, 1L, 2L, 2L, 2L, 2L, 1L, 3L, 2L, 2L), .Label = c("low", "medium",
"high"), class = "factor"), Q4 = c(2, 3, 3, 5, 4, 3, 4, 5, 2,
4, 2, 3, 5, 4, 3, 3, 5, 5, 4, 5, 3, 2, 4, 1, 5, 4, 4, 4, 4, 4,
5, 3, 5, 1, 5, 5, 4, 5, 4, 1, 4, 2, 1, 5, 4)), row.names = c(NA,
-45L), class = c("tbl_df", "tbl", "data.frame"))
df <- select(climate_experience_data, Q52_bin, Q53_bin, Q57_bin, Q4)
names(df) <- c("Q52_bin", "Q53_bin", "Q57_bin", "response")
facet_names <- c(`Q52_bin` = "Spirituality", `Q53_bin` = "Politics L/R", `Q57_bin` = "Religiosity", `low`="low", `medium`="medium", `high`="high")
facet_labeller <- function(variable,value){return(facet_names[value])}
q4_levels = c("Not at all", "A little", "Some", "A lot", "A great deal")
df$response <- factor(df$response, ordered = TRUE, levels = c("5", "4", "3", "2", "1"))
df$response <- fct_recode(df$response, "Not at all" = "1", "A little" = "2", "Some" = "3", "A lot" = "4", "A great deal" = "5")
caption <- "How much have you thought about climate change before today?"
df %>%
# we need to get the data including facet info in long format, so we use pivot_longer()
pivot_longer(!response, names_to = "bin_name", values_to = "b") %>%
# add counts for plot below
count(response, bin_name, b) %>%
group_by(bin_name,b) %>%
mutate(perc=paste0(round(n*100/sum(n),1),"%")) %>%
# run ggplot
ggplot(aes(x = n, y = "", fill = response, label = perc))
geom_col(position=position_fill(), aes(fill=response))
coord_cartesian(clip = "off")
geom_label_repel(
fill = "white",
size = 3,
min.segment.length = 0,
max.overlaps = Inf,
position = position_fill()
)
scale_fill_brewer(palette="YlOrBr")
scale_x_continuous(labels = scales::percent_format(), expand = c(0.05, 0.05))
facet_grid(vars(b), vars(bin_name), labeller=as_labeller(facet_names))
labs(caption = caption, x = "", y = "")
guides(fill = guide_legend(title = NULL))
ggsave("figures/q4_faceted.png", width = 30, height = 10, units = "cm")
Here's the visual that I'm getting:
So what's going on here in terms of labels reversing? I'm concerned that there may be something about the plot that is inaccurate!
CodePudding user response:
The issue is that the grouping variable used for your labels is different from the one used for the columns. To fix that you have to explicitly tell ggrepel to group the labels by response
using the group
aes:
library(tidyverse)
library(ggrepel)
df_long <- df %>%
pivot_longer(!response, names_to = "bin_name", values_to = "b") %>%
count(response, bin_name, b) %>%
group_by(bin_name, b) %>%
mutate(perc = paste0(round(n * 100 / sum(n), 1), "%"))
ggplot(df_long, aes(x = n, y = ""))
geom_col(position = position_fill(), aes(fill = response))
coord_cartesian(clip = "off")
geom_label_repel(
aes(group = response, label = perc),
fill = "white",
size = 3,
min.segment.length = 0,
max.overlaps = Inf,
position = position_fill()
)
scale_fill_brewer(palette = "YlOrBr")
scale_x_continuous(labels = scales::percent_format(), expand = c(0.05, 0.05))
facet_grid(vars(b), vars(bin_name), labeller = as_labeller(facet_names))
labs(caption = caption, x = "", y = "")
guides(fill = guide_legend(title = NULL))