为什么 Advanced R 会声称您不能提供不随 Map 变化的参数?

Why would Advanced R claim that you cannot supply arguments that do not vary to Map?

Advanced R 的作者当然比我更了解 R。但是,Section 9.4.5 包含以下声明:

Map() vectorises over all arguments so you cannot supply arguments that do not vary.

但这显然是错误的。例如,我可以轻松编写以下内容:

> Map(function(x,y) x+y,1:3,runif(1))
[[1]]
[1] 1.224857

[[2]]
[1] 2.224857

[[3]]
[1] 3.224857

事实上,在作者自己的 purrr:map 函数中发现了相同的功能:

purrr::map(1:3,function(x,y) x+y,runif(1))
[[1]]
[1] 1.729889

[[2]]
[1] 2.729889

[[3]]
[1] 3.729889

那么作者可能一直在谈论什么?我觉得我只是误读了,section 9.2.3purrr::map:

中展示了相同类型的功能这一事实强烈地加强了猜测
plus <- function(x, y) x + y

x <- c(0, 0, 0, 0)
map_dbl(x, plus, runif(1))
#> [1] 0.0625 0.0625 0.0625 0.0625
map_dbl(x, ~ plus(.x, runif(1)))
#> [1] 0.903 0.132 0.629 0.945

那么上面的引用指的是 Map 中的什么缺陷?

Mapmapply:

的包装器
Map <- function (f, ...) 
{
  f <- match.fun(f)
  mapply(FUN = f, ..., SIMPLIFY = FALSE)
}

mapply 的文档告诉我们:

mapply calls FUN for the values of ... (re-cycled to the length of the longest, unless any have length zero), followed by the arguments given in MoreArgs. The arguments in the call will be named if ... or MoreArgs are named.

这意味着即使您提供了一个不应该变化的参数,它也会作为一个向量被回收,而不是像标准函数参数那样保持原样。

如果不变的参数本身是一个向量,这就会有很大的不同:

f <- function(x,coef) {paste(coef[1],'*', x ,'+',coef[2])}

Map(f,1:3,c(2,3))
[[1]]
[1] "2 * 1 + NA"

[[2]]
[1] "3 * 2 + NA"

[[3]]
[1] "2 * 3 + NA"

Warning message:
In mapply(FUN = f, ..., SIMPLIFY = FALSE) :
  longer argument is not a multiple of length of shorter

相反,purrr::map 允许参数不变,这两个示例之间的差异说明了上述引用的作者可能的意思:

purrr::map(1:3,f,c(2,3))

[[1]]
[1] "2 * 1 + 3"

[[2]]
[1] "2 * 2 + 3"

[[3]]
[1] "2 * 3 + 3"