R purrr:::pmap: how to refer to input arguments by name?

Matifou picture Matifou · Jan 26, 2017 · Viewed 7.5k times · Source

I am using R purrr:::pmap with three inputs. It is not clear how I can refer explicitly to these inputs in the formula call? When using map2, the formula call goes as ~ .x + .y. But how to do when using pmap?

Reproducing Hadley's example from http://r4ds.had.co.nz/lists.html

library(purrr)
mu <- list(5, 10, -3)
sigma <- list(1, 5, 10)
n <- list(1, 3, 5)

args2 <- list(mean = mu, sd = sigma, n = n)
pmap(args2, rnorm)

If I want to refer explicitly to the input arguments when calling rnorm, I can use:

pmap(args2, function(mean, sd, n) rnorm(n, mean, sd))

But say I want to do this with the formula approach. How do I do that? This for example does not work:

pmap(args2, ~rnorm(n=.n, mean=.mean, sd=.sd))

Thanks!!

Answer

Aur&#232;le picture Aurèle · Nov 29, 2017

Since version 0.2.3 you can use ..1, ..2, ..3 and so on:

pmap(args2, ~ rnorm(..3, ..1, ..2))

But... I've already ran into trouble with this syntax, for instance with replicate:

pmap(list(1, 2), ~ replicate(n = ..1, expr = ..2))
# Error in FUN(X[[i]], ...) : the ... list does not contain 2 elements

Probably because of:

print(replicate)
# function (n, expr, simplify = "array") 
#   sapply(integer(n), eval.parent(substitute(function(...) expr)), 
#          simplify = simplify)

It seems the function(...) expr in substitute() does not play well with ..2, being interpreted as the second element of ... which is empty.

Note that pmap(list(1, 2), ~ replicate(n = ..1, expr = .y)) still works.