为什么Map只需要一组向量作为参数,而mapply需要一组向量和MoreArgs参数?
据我所知,除了简化之外,可以mapply用Map. 毕竟,Map是mapply. 但是,我很惊讶地看到它mapply需要一...组参数(文档称之为“要向量化的参数(严格为正长度的向量或列表,或所有长度为零) ”)和MoreArgs所需函数顶部的参数f,Map而不使用MoreArgs, 只需要...(文档称之为“向量”)和f.
我的问题是:为什么mapply需要MoreArgs但Map不需要?能做不能mapply做的事Map吗?或者是mapply试图让一些更容易的事情变得更难Map?如果是这样,那又怎样?
我怀疑这sapply可能是答案的有用参考点。这可能有助于它的比较X,FUN以及...参数mapply的...和MoreArgs。
回答
让我们看一下代码Map:
Map
function (f, ...)
{
f <- match.fun(f)
mapply(FUN = f, ..., SIMPLIFY = FALSE)
}
Map
function (f, ...)
{
f <- match.fun(f)
mapply(FUN = f, ..., SIMPLIFY = FALSE)
}
正如您所写,它只是一个包装器,点被转发到mapply,请注意,它SIMPLIFY被硬编码为FALSE
为什么 mapply 需要
MoreArgs但Map不需要?
这是一个设计选择,可能部分是由于历史原因,我不会介意明确MoreArgs和USE.NAMES论点(或与此相关的SIMPLIFY = TRUE论点),但我相信基本原理是Map简单的,如果你想调整参数鼓励您使用mapply. 不过,你可以使用MoreArgs和USE.NAMES使用Map,他们会点穿越到mapply呼叫,虽然它是无证,作为文档描述的...说法是“载体”。
等效的mapply调用将是:
Map(sum, setNames(1:2, c("a", "b")), 1:2)
#> $a
#> [1] 2
#>
#> $b
#> [1] 4
Map(sum, setNames(1:2, c("a", "b")), 1:2, USE.NAMES = FALSE)
#> [[1]]
#> [1] 2
#>
#> [[2]]
#> [1] 4
Map(
replicate,
2:3,
c(FALSE, TRUE),
MoreArgs = list(expr = quote(runif(1))))
#> [[1]]
#> [[1]][[1]]
#> [1] 0.7523955
#>
#> [[1]][[2]]
#> [1] 0.4922519
#>
#>
#> [[2]]
#> [1] 0.81626690 0.07415023 0.56264388
mapply 可以做一些 Map 不能做的事情吗?还是 mapply 试图让 Map 变得更容易一些?如果是这样,那又怎样?
您不能SIMPLIFY与 一起使用Map:
Map(sum, 1:3, 1:3, SIMPLIFY = TRUE)
#> Error in mapply(FUN = f, ..., SIMPLIFY = FALSE): formal argument "SIMPLIFY" matched by multiple actual arguments
一点历史
mapply引入了 R 1.7.0Map在 R 2.6 中引入,新闻条目如下:
新的高阶函数 Reduce()、Filter() 和 Map()。
该f参数名称的功能共享和他们在同一页上记录。我不知道为什么放弃命名函数的原因FUN,但是这 3 个函数(以及 中记录的其他函数?Reduce)之间的一致性解释了为什么mapply并且Map不要以相同的方式命名它们的函数参数(一致性也解释了大写M我猜测)。
在文档中,我们还可以阅读:
Map是一个简单的包装器,mapply它不会试图简化结果,类似于 Common Lisp 的 mapcar(但是参数被回收)。未来的版本可能允许对结果类型进行一些控制。
所以,理论上,正如我从最后一句话中所理解的,Map可以升级以提供某种类型的稳定性,类似于什么vapply。在我看来,R-devel 并没有一路走好,因为他们想花时间来正确决定要做什么,从那时起他们就一直保持这种状态。