I'm trying to automate my creation of ggplot slides using pmap from the purrr package. As an extension of this question, I'm trying to facet based on the group membership variables in my data (level and location).
Unlike the previous question, I know have 3 inputs, so I need to use pmap() instead of map2(), and for some reason I keep getting this error:
Error: Only strings can be converted to symbols
Run `rlang::last_error()` to see where the error occurred.
And when I do dig into the error, it shows the problem is in my first pmap() call:
<error/rlang_error>
Only strings can be converted to symbols
Backtrace:
1. purrr::pmap(...)
14. rlang::sym(variable)
I've tried every combination, but I can't crack it. I want R to iterate every plot by level and location.
Here's my code and data:
#Packages
library(dplyr)
library(purrr)
library(ggplot2)
#Data
test <- tibble(s1 = c("Agree", "Neutral", "Strongly disagree"),
s2rl = c("Agree", "Neutral", "Strongly disagree"),
f1 = c("Strongly agree", "Disagree", "Strongly disagree"),
f2rl = c("Strongly agree", "Disagree", "Strongly disagree"),
level = c("Manager", "Employee", "Employee"),
location = c("USA", "USA", "AUS"))
#Get just test items for name
test_items <- test %>%
dplyr::select(s1, s2rl, f1, f2rl)
#titles of plots for R to iterate over
titles <- c("S1 results", "Results for S2RL", "Fiscal Results for F1", "Financial Status of F2RL")
#group levels
group_name <- c("level", "location")
#custom ggplot function
faceted_plots = function(variable, group, title) {
sample_size <- test %>%
group_by(!! rlang::sym(group), !! rlang::sym(variable)) %>%
summarize(n = sum(!is.na(!! rlang::sym(variable))))
test %>%
count(!! rlang::sym(group), !! rlang::sym(variable)) %>%
mutate(percent = 100*(n / sample_size$n)) %>%
drop_na() %>%
ggplot(aes(x = !! rlang::sym(variable), y = percent, fill = .data[[variable]])) +
geom_bar(stat = "identity") +
geom_text(aes(label= paste0(percent, "%"), fontface = "bold", family = "Arial", size=14), vjust= 0, hjust = -.5) +
ylab("\nPercentage") +
labs(
title = title,
subtitle = paste0("(N = ", sample_size$n, ")")) +
coord_flip() +
theme_minimal() +
scale_fill_manual(values = c("Strongly disagree" = "#CA001B", "Disagree" = "#1D28B0", "Neutral" = "#D71DA4", "Agree" = "#00A3AD", "Strongly agree" = "#FF8200")) +
scale_x_discrete(labels = c("Strongly disagree" = "Strongly\nDisagree", "Disagree" = "Disagree", "Neutral" = "Neutral", "Agree" = "Agree", "Strongly agree" = "Strongly\nAgree"), drop = FALSE) +
theme(axis.title.y = element_blank(),
axis.text = element_text(size = 14, color = "gray28", face = "bold", hjust = .5),
axis.title.x = element_text(size = 18, color = "gray32", face = "bold"),
legend.position = "none",
text = element_text(family = "Arial"),
plot.title = element_text(size = 20, color = "gray32", face = "bold", hjust = .5),
plot.subtitle = element_text(size = 16, color = "gray32", face = "bold", hjust = .5),
panel.spacing.x = unit(2, "lines")) +
ylim(0, 100) +
facet_grid(~!! rlang::sym(group))
}
#pmap call
plots_and_facet <- pmap(
list(x = names(test_items),
y= titles,
z = group_name),
faceted_plots(test_items, titles, group_name))
EDIT with Mr. Flick's solution--it works! Disregard any of the issues with the counting, as that was on my end and is out of scope for this question:
#custom ggplot function
faceted_plots = function(variable, group, title) {
sample_size <- test %>%
group_by(.data[[group]], .data[[variable]]) %>%
summarize(n = sum(!is.na(.data[[variable]])))
test %>%
count(.data[[group]], .data[[variable]]) %>%
mutate(percent = 100*(n / sample_size$n)) %>%
drop_na() %>%
ggplot(aes(x = .data[[variable]], y = percent, fill = .data[[variable]])) +
geom_bar(stat = "identity") +
geom_text(aes(label= paste0(percent, "%"), fontface = "bold", family = "Arial", size=14), vjust= 0, hjust = -.5) +
ylab("\nPercentage") +
labs(
title = title,
subtitle = paste0("(N = ", sample_size$n, ")")) +
coord_flip() +
theme_minimal() +
scale_fill_manual(values = c("Strongly disagree" = "#CA001B", "Disagree" = "#1D28B0", "Neutral" = "#D71DA4", "Agree" = "#00A3AD", "Strongly agree" = "#FF8200")) +
scale_x_discrete(labels = c("Strongly disagree" = "Strongly\nDisagree", "Disagree" = "Disagree", "Neutral" = "Neutral", "Agree" = "Agree", "Strongly agree" = "Strongly\nAgree"), drop = FALSE) +
theme(axis.title.y = element_blank(),
axis.text = element_text(size = 14, color = "gray28", face = "bold", hjust = .5),
axis.title.x = element_text(size = 18, color = "gray32", face = "bold"),
legend.position = "none",
text = element_text(family = "Arial"),
plot.title = element_text(size = 20, color = "gray32", face = "bold", hjust = .5),
plot.subtitle = element_text(size = 16, color = "gray32", face = "bold", hjust = .5),
panel.spacing.x = unit(2, "lines")) +
ylim(0, 100) +
facet_grid(~.data[[group]])
}
#pmap call
expand_grid(tibble(item = names(test_items), title=titles),
group = group_name) %>%
pmap(function(item, group, title)
faceted_plots(item, group, title))