I'm trying to get better with pmap(), but I'm hitting some errors. In this example, I have a simple graphing function that I want to iterate over. My understanding of pmap() is that I can set and define an infinite number of parameters. However, I'm confused why it is saying that .z isn't defined when I so clearly have it defined.
Unless necessary, I'm not interested in changing any of the ways the arguments are defined--I just want to understand and fix why I can't have this 3rd argument, even though .x and .y work fine (even if I switch around what is defined as .x, .y, and .z).
library(purrr)
library(ggplot2)
library(dplyr)
#Plot function
make_chart <- function(data, x, y, xtitle){
require(stringr)
ggplot(data, aes(x = as.factor({{x}}), y = {{y}})) +
geom_col() +
ggtitle(paste0("Number of ", str_to_title({{xtitle}}), " by MPG")) +
xlab({{xtitle}})
}
#Define x variables
x_variables <- c("cyl", "vs", "am", "gear", "carb")
#pmap it--why is .z not found and how do I get it to be?
pmap(list(.x = mtcars %>% dplyr::select(matches(x_variables)),
.y = x_variables,
.z = mtcars %>% dplyr::select(mpg)),
~mtcars %>%
make_chart(x = .x, xtitle = .y, y = .z))
Another option to the ones offered by @shafee would be to pass a named list
to pmap
with the names of the function arguments. Doing so we don't need an anonymous function which merely maps the names of the list
passed to pmap
to the names of the function arguments.
Moreover, at least from a ggplot2
standpoint best practice to create your loop would be to loop over the column names (and making use of the .data
pronoun) instead of passing vectors to your function. Actually, doing so you could get rid of the xtitle
argument and replace xtitle
by x
in the plotting function.
library(purrr)
library(ggplot2)
library(stringr)
make_chart <- function(data, x, y, xtitle) {
ggplot(data, aes(x = as.factor(.data[[x]]), y = .data[[y]])) +
geom_col() +
ggtitle(paste0("Number of ", str_to_title(xtitle), " by MPG")) +
xlab(xtitle)
}
x_variables <- c("cyl", "vs", "am", "gear", "carb")
pmap(
list(
x = x_variables,
xtitle = x_variables,
y = "mpg"
),
make_chart,
data = mtcars
)
#> [[1]]
#>
#> [[2]]