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!!
You can use with(...)
to solve this :
pmap(args2, ~with(list(...),rnorm(n, mean, sd)))
# [[1]]
# [1] 2.733528
#
# [[2]]
# [1] 4.0967533 6.4926143 0.6083532
#
# [[3]]
# [1] 1.8836592 -0.2090425 -4.0030168 1.1834931 3.2771316
More explanations here: Harnessing .f list names with purrr::pmap
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.
It seems that pmap
cannot access the arguments in a list by its name in the formula interface.
You can check in https://github.com/hadley/purrr/issues/203.
For instance you can do :
pmap(list(1:2, 5:6), ~ .x + .y)
Thus the first element of the list is referred by .x
and the second by .y
.
However if you try to name the argument of the list as in
pmap(list(a = 1:2, b = 5:6), ~ .a + .b)
then you will have the error:
Error in .f(a = .l[[c(1L, i)]], b = .l[[c(2L, i)]], ...) :
unused arguments (a = .l[[c(1, i)]], b = .l[[c(2, i)]])
I think that in the formula interface of the function pmap
the best you could do if you want to use the formula interface and not use function(mean , sd, n)
is to :
.x
and .y
)You can thus use thus fix the value of your third argument n
(for instance n = 4
) you want and then run:
mu <- list(5, 10, -3)
sigma <- list(1, 5, 10)
set.seed(1)
pmap(list(mu,sigma), ~ rnorm(mean = .x, sd = .y, n = 4))
Which will return :
[[1]]
[1] 4.373546 5.183643 4.164371 6.595281
[[2]]
[1] 11.647539 5.897658 12.437145 13.691624
[[3]]
[1] 2.7578135 -6.0538839 12.1178117 0.8984324
[[4]]
[1] 9.136278 4.355900 14.374793 10.865199
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With