【发布时间】:2013-08-09 05:50:33
【问题描述】:
在@hadley 的article on functionals referenced in an answer today 的提示下,我决定重新审视一个关于outer 函数如何工作(或不工作)的难题。为什么会失败:
outer(0:5, 0:6, sum) # while outer(0:5, 0:6, "+") succeeds
这表明我认为outer应该处理像sum这样的函数:
Outer <- function(x,y,fun) {
mat <- matrix(NA, length(x), length(y))
for (i in seq_along(x)) {
for (j in seq_along(y)) {mat[i,j] <- fun(x[i],y[j])} }
mat}
> Outer(0:5, 0:6, `+`)
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0 1 2 3 4 5 6
[2,] 1 2 3 4 5 6 7
[3,] 2 3 4 5 6 7 8
[4,] 3 4 5 6 7 8 9
[5,] 4 5 6 7 8 9 10
[6,] 5 6 7 8 9 10 11
好的,对于该示例,我的索引没有完全对齐,但修复起来并不难。问题是为什么像sum 这样应该能够接受两个参数并返回适合矩阵元素的(原子)值的函数在传递给base::outer 函数时却不能这样做?
所以@agstudy 为Outer 的更紧凑版本提供了灵感,而他的版本更加紧凑:
Outer <- function(x,y,fun) {
mat <- matrix(mapply(fun, rep(x, length(y)),
rep(y, each=length(x))),
length(x), length(y))
但是,问题仍然存在。术语“矢量化”在这里有些含糊,我认为“二元”更正确,因为sin 和cos 在该术语的通常意义上是“矢量化”的。期望outer 以可以使用非二元函数的方式扩展其参数是否存在基本的逻辑障碍。
这是另一个outer-error,可能与我对这个问题缺乏了解类似:
> Vectorize(sum)
function (..., na.rm = FALSE) .Primitive("sum")
> outer(0:5, 0:6, function(x,y) Vectorize(sum)(x,y) )
Error in outer(0:5, 0:6, function(x, y) Vectorize(sum)(x, y)) :
dims [product 42] do not match the length of object [1]
【问题讨论】:
-
你的函数没问题,但我猜要慢得多,所以对于
outer的 R 实现来说不是很好;已经用 C++ 实现了 outer,那么sum版本可能会起作用 -
你在最后一个例子中寻找这个:
outer(0:5, 0:6, Vectorize(function(x,y)sum(x,y))) -
@eddi:如果提供答案,我会赞成。
-
您的报告函数可能会有所帮助,但仅将“矢量化”包裹在函数周围并不足以确保成功。 @eddi 的版本更好。
标签: r functional-programming vectorization