Why do function argument names need to match list names with pmap?

Viewed 138

I am trying to understand why this code works:

tmp <- list(this = list(1:5), 
            that = list(10*c(1:5)), 
            other = list(100*c(1:5))) 

tmp %>% pmap(function(this, that, other) paste(this, that, other))

... but the following code produces an "unused arguments" error:

tmp %>% pmap(function(a, b, c) paste(a, b, c))

I came across this GitHub post, but I'm still not clear on how it might apply.. thanks!

3 Answers

Unless I am missunderstanding your question, the second doesn't work because a, b and c are not list elements that are attached in the pmap's calling environment.

If you named the list elements a, b and c, it would work.

tmp2 <- list(a = list(1:5), 
            b = list(10*c(1:5)), 
            c = list(100*c(1:5))) 

tmp2 %>% pmap(function(a, b, c) paste(a, b, c))
#[[1]]
#[1] "1 10 100" "2 20 200" "3 30 300" "4 40 400" "5 50 500"

Could you have objects named a, b or c in your global environment? I get a different error message.

tmp %>% pmap(function(a, b, c) paste(a, b, c))
#Error in .f(this = .l[[1L]][[1L]], that = .l[[2L]][[1L]], other = .l[[3L]][[1L]],  : 
#  unused arguments (this = .l[[1]][[1]], that = .l[[2]][[1]], other = .l[[3]][[1]])

packageVersion("purrr")
#[1] ‘0.3.3’

We can do this without any anonymous function

library(purrr)
library(dplyr)
tmp %>%
     pmap(paste)
#[[1]]
#[1] "1 10 100" "2 20 200" "3 30 300" "4 40 400" "5 50 500"

Also, with tidyverse, the anonymous syntax can be

tmp %>%
   pmap(~ paste(..1, ..2, ..3))
#[[1]]
#[1] "1 10 100" "2 20 200" "3 30 300" "4 40 400" "5 50 500"

If you have a named list as shown in the example, you need to refer them with their respective names in an anonymous function. Hence, this works for a named list

library(purrr)
tmp %>% pmap(function(this, that, other) paste(this, that, other))

and this does not.

tmp %>% pmap(function(a, b, c) paste(a, b, c))

If you remove the names of the list then you can use any variable in the argument.

unname(tmp) %>% pmap(function(a, b, c) paste(a, b, c))

#[[1]]
#[1] "1 10 100" "2 20 200" "3 30 300" "4 40 400" "5 50 500"
Related