This is a question for which I've written failsafes in my code before, but I'm wondering if there's something more straightforward that I've missed.
I sometimes have 2 (or more) lists that contain different types of information that need to work together with a function such as map2
—think a named list of ggplot
objects and a named list of file paths for saving output of each. Is there a way built-in or easily added to a piped workflow to make sure list items are matched by name rather than by position?
Consider a simple example:
library(purrr)
evens <- list(a = 2, b = 4, c = 6, d = 8)
odds <- list(a = 11, d = 9, c = 7, b = 5)
map2
returns a list with the same names as the first list, and iterates by position. So the fact that items b
and d
are switched in odds
isn't addressed, and these two calls come out with different results:
map2(evens, odds, function(l1, l2) {
paste(l1, l2)
})
#> $a
#> [1] "2 11"
#>
#> $b
#> [1] "4 9"
#>
#> $c
#> [1] "6 7"
#>
#> $d
#> [1] "8 5"
map2(odds, evens, function(l1, l2) {
paste(l1, l2)
})
#> $a
#> [1] "11 2"
#>
#> $d
#> [1] "9 4"
#>
#> $c
#> [1] "7 6"
#>
#> $b
#> [1] "5 8"
What I've done in the past is to instead use imap
and use the names of the first list to extract the appropriate item in the other list, but that means no longer having that second list in my function arguments:
imap(evens, function(l1, name) {
paste(l1, odds[[name]])
})
#> $a
#> [1] "2 11"
#>
#> $b
#> [1] "4 5"
#>
#> $c
#> [1] "6 7"
#>
#> $d
#> [1] "8 9"
If I want to feel like I'm operating more evenly over both lists, I could order them each by name, but this feels clunky:
map2(
evens[order(names(evens))],
odds[order(names(odds))],
function(l1, l2) paste(l1, l2)
)
# same output as previous
Or clunkier still, make a list of the two lists, order them each in another map
, then pipe that into pmap
since it takes a list of lists:
list(evens, odds) %>%
map(~.[order(names(.))]) %>%
pmap(function(l1, l2) paste(l1, l2))
# same output as previous
Ideally, I'd like to combine the safety of the imap
option with the cleanliness of map2
.