I have two lists foo
and bar
, where length(foo) > length(bar)
. I want to apply a function length(bar)
times to each element of bar
and store the output of each application in is own list and store all of the applications of the function to each element of bar
in their own lists. This nested list output structure is important as I am passing it to functions that require nested lists. Examples of what I have and desired are in the minimal example.
While this works nicely with nested for-loops, I've been trying to accomplish this with purrr
's map
functions. I've managed to do this by creating (a) a list of length(bar)
where each element is foo
, (b) passing this new list and bar
to an anonymous function in purrr::pmap()
, and then (c) passing this to an anonymous function in purrr:map()
.
While this works, it seems very antithetical to the purpose of purrr
:
- Instead of
.x
,.y
, and~
syntax, I'm defining anonymous functions. - Instead of passing my raw lists (which vary in length), I'm converting one to a nested list to match the other's length. This can be memory-intensive, slow, etc.
- I'm working with nested lists rather than flatter lists/dataframes I then partition into my desired data structure.
Is there an alternative way of working with different-length lists in purrr
than my aproach? How might I modify my code (minimal example below) to better-exploit the syntax of purrr
? One idea (Handling vectors of different lengths in purrr) is to use cross()
or some equivalent to generate a single object for passing to pmap()
, but I'm not how how to then generate the nested list structure.
library(purrr)
# Example data: 2 different-length lists
foo <- list(1, 2, 3)
bar <- list("df1", "df2")
# Desired output:
out <- list(list("df1_1", "df1_2", "df1_3"),
list("df2_1", "df2_2", "df2_3"))
# Distinctive features of output:
#length(out) == length(bar)
#length(out[[1]]) == length(out[[2]])
#length(out[[1]]) == length(foo)
# Can use purrr::pmap but this will concurrently
# iterate through each element of inputs ("in
# parallel") so need to create same-length inputs
foo_list <- rep(list(foo), 2)
# Pass our inputs to pmap then use map to iterate
# over foo contained in each foo_list element.
purrr::pmap(list(foo_list, bar),
function(foo, bar) {
map(foo, function(i) {
paste0(bar, "_", i)
})
})