1

I am wanting to learn more about the purrr package. I can see some nicities in conssistency but am struggling with flexibility for arbitrary problems. I have always loved the flexibility and relative ease of use of Map. I have read about pmap but it seems more awkward to work with than Map for a situation where you want to pass an object to the next part and have n lists loop over that object in concert with one another.

Below is a minimal example. The code passes mtcars on to a loop (Map in this case) that in turn iterates through writing functions and file extensions and uses the mtcars from the prior chain to write out a file. How could I write this code using a purrr/tidyverse approach?

I appreciate that I could simply pass c('fst', 'csv') and build the extension and writing functions from a single vector using match.call. This MWE is meant to show the need to pass 2 or more lists/vectors over an object being passed along a chain (this obect is in a sense static).

library(tidyverse)
library(fst)

mtcars %>%
    {Map(function(fun, ext) {
            fun(., sprintf('mtcars.%s', ext))
        }, 
        list(fst::write_fst, readr::write_csv), 
        list('fst', 'csv')
    )} %>%
    invisible()
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • It looks similar as this [question](https://stackoverflow.com/questions/43966104/handling-vectors-of-different-lengths-in-purrr) Or considering to use the invoke_map() in purrr package – FENG QI May 08 '18 at 15:20

1 Answers1

4

You can use invoke_map to call a list of functions with a list of arguments, as well as arguments shared by all the functions in the list.

The tricky part was getting the list of paths properly nested, since it needs to be a list of lists. You can do this all in one line, rather than saving funs and paths first; I did it this way just for clarity.

library(tidyverse)

funs <- list(fst::write_fst, readr::write_csv)
paths <- map(list("fst", "csv"), ~list(path = sprintf("mtcars.%s", .)))

invoke_map(funs, paths, x = mtcars)

As it maps over the two functions, they both print out mtcars to the console. Not ideal, but there isn't an invoke version of the walk functions as far as I can tell, which use side effects rather than returning the data frame. This saves the files "mtcars.fst" and "mtcars.csv".

camille
  • 16,432
  • 18
  • 38
  • 60