R purrr ::: pmap:如何按名称引用输入参数?

Mat*_*fou 15 r purrr tidyverse

purrr:::pmap用三个输入R.目前尚不清楚我如何在公式调用中明确引用这些输入?使用map2时,公式调用如下~ .x + .y.但使用时该怎么办pmap

http://r4ds.had.co.nz/lists.html转载Hadley的例子

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)
Run Code Online (Sandbox Code Playgroud)

如果我想在调用时显式引用输入参数rnorm,我可以使用:

pmap(args2, function(mean, sd, n) rnorm(n, mean, sd))
Run Code Online (Sandbox Code Playgroud)

但是说我想用公式方法做到这一点.我怎么做?例如,这不起作用:

pmap(args2, ~rnorm(n=.n, mean=.mean, sd=.sd))
Run Code Online (Sandbox Code Playgroud)

谢谢!!

Aur*_*èle 10

由于版本0.2.3,您可以使用..1,..2,..3等:

pmap(args2, ~ rnorm(..3, ..1, ..2))
Run Code Online (Sandbox Code Playgroud)

但是......我已经遇到了这种语法的麻烦,例如replicate:

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

可能是因为:

print(replicate)
# function (n, expr, simplify = "array") 
#   sapply(integer(n), eval.parent(substitute(function(...) expr)), 
#          simplify = simplify)
Run Code Online (Sandbox Code Playgroud)

似乎function(...) exprin substitute()不能很好地..2被解释为第二个元素...是空的.

请注意,pmap(list(1, 2), ~ replicate(n = ..1, expr = .y))仍然有效.


Moo*_*per 6

你可以with(...)用来解决这个问题:

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
Run Code Online (Sandbox Code Playgroud)

这里有更多解释:利用purrr :: pmap利用.f列表名称


Eti*_*ler 5

似乎pmap无法通过公式界面中的名称访问列表中的参数。您可以查看https://github.com/hadley/purrr/issues/203

例如你可以这样做:

pmap(list(1:2, 5:6), ~ .x + .y)
Run Code Online (Sandbox Code Playgroud)

因此,列表的第一个元素被引用,.x第二个元素被引用.y。但是,如果您尝试将列表的参数命名为

pmap(list(a = 1:2, b =  5:6), ~ .a + .b)
Run Code Online (Sandbox Code Playgroud)

然后你会得到错误:

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)]])
Run Code Online (Sandbox Code Playgroud)

我认为在函数的公式界面中,pmap如果您想使用公式界面而不使用,您可以做的最好的事情function(mean , sd, n)是:

  1. 不命名列表中的元素
  2. 不使用两个以上的参数(为了使用隐式名称.x.y

因此,您可以使用因此修复您想要的第三个参数n(例如n = 4)的值,然后运行:

mu <- list(5, 10, -3)
sigma <- list(1, 5, 10)
set.seed(1)
pmap(list(mu,sigma), ~ rnorm(mean = .x, sd = .y, n = 4))
Run Code Online (Sandbox Code Playgroud)

哪个将返回:

[[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
Run Code Online (Sandbox Code Playgroud)