0

I am trying to automate my bar graphs by writing a function which will take different datasets and x and y axis values.

Since the function has three arguments(dataset, x-axis and y-axis), I am using pmap() from purrr.

The function works fine when I remove the dataset argument and use map2() instead of pmap()

Here's the code I have written:

forest_day <- forest %>% group_by(day) %>% summarise(n())%>%rename(count1 = `n()`)
forest_month <- forest %>% group_by(month) %>% summarise(n())%>%rename(count1 = `n()`)

pbar <- function(data, x, y) {
  ggplot(data = data) + aes_string(x = x, y = y) + geom_bar(stat = 'identity')
}

l1 <- list(forest_month, forest_month$month, forest_month$count1)
pmap(l1, pbar)
l2 <- list(forest_day, forest_day$day, forest_day$count1)
pmap(l2,pbar)

The error code I get when using pmap() is this:

"Element 1 of .l must have length 1 or 12, not 2"

Thanks in advance for help!

10618890
  • 5
  • 1
  • 5

1 Answers1

1

Since I do not have your data, I generate my own data sets using mtcars and iris. Using get(data) in your ggplot call should solve your problem. Note that you need to provide all arguments as strings. In your own example you already use aes_string therefore x and y should be supplied as strings. Using get takes a string as argument and looks for the object in your global environment.

library(dplyr)
library(ggplot2)
library(purrr)

mtcars_cyl <- mtcars %>% group_by(cyl) %>% summarise(count1 = n())
iris_Species <- iris %>% group_by(Species) %>% summarise(count1 = n())

pbar <- function(data, x, y) {
  ggplot(data = get(data), aes_string(x = x, y = y)) + geom_bar(stat = 'identity')
}

l1 <- list("mtcars_cyl","cyl", "count1")
pmap(l1, pbar)
map2("cyl", "count1" )
l2 <- list("iris_Species", "Species", "count1")
pmap(l2,pbar)

In case you always use the same y-variable count1. Then you can use map2. Here is an example where you have two lists. One list, ls_data, providing the data frames to loop over and one list, ls_x, providing the x-argument to ggplot2. count1 is then defined within the lambda function inside map2. Calling map2 produced both plots at once. Alternatively walk2 will produce the plots without printing [[1]] [[2]] to the console.

ls_data <- list("mtcars_cyl","iris_Species")
ls_x <- list("cyl","Species")

map2(ls_data, ls_x, ~ pbar(.x, .y, "count1"))
walk2(ls_data, ls_x, ~ pbar(.x, .y, "count1"))

Another way of calling map2 is to put both arguments in a named list, with the name of the data sets as list name and the x-argument as list input.

args <- c(mtcars_cyl = "cyl",
          iris_Species = "Species")

map2(names(args), args, ~ pbar(.x, .y, "count1"))

Good luck with your data.

TimTeaFan
  • 17,549
  • 4
  • 18
  • 39