问题描述
由@ hadley提供,我决定重新讨论一下关于 outer 函数如何工作(或不)的持久难题。为什么会失败:
Prompted by @hadley's article on functionals referenced in an answer today, I decided to revisit a persistent puzzle about how the outer function works (or doesn't). Why does this fail:
outer(0:5, 0:6, sum) # while outer(0:5, 0:6, "+") succeeds
这表明我认为 outer 应该处理像 sum 这样的函数:
This shows how I think outer should handle a function like 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 function?
OK, I don't have my indices exactly aligned for that example, but it wouldn't be that hard to fix. The question is why a function like sum that should be able to accept two arguments and return an (atomic) value suitable for a matrix element, cannot do so when passed to the base::outer function?
因此@agstudy给出了一个更紧凑版本的 Outer 并且他更紧凑:
So @agstudy has given inspiration for a more compact version of Outer and his is even more compact:
Outer <- function(x,y,fun) { mat <- matrix(mapply(fun, rep(x, length(y)), rep(y, each=length(x))), length(x), length(y))
但问题仍然存在。因为 sin 和 cos 是vectorized这个词在这里有点含糊不清,我认为dyadic更正确通常意义上的矢量化。期望 outer 以非二元函数可以使用的方式扩展其参数是否存在根本的逻辑障碍。
However, the question remains. The term "vectorized" is somewhat ambiguous here and I think "dyadic" is more correct, since sin and cos are "vectorized" in the usual sense of the term. Is there a fundamental logical barrier to expecting outer to expand its arguments in a manner that non-dyadic functions can be used.
以下是另外一个外部 - 错误,这可能与我对此问题缺乏理解相关:
And here's another outer-error that is probably similarly connected to my lack of understanding of this issue:
> 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(0:5,0:6,sum)不起作用,因为 sum 不是矢量化的(意思是返回一个与其两个参数长度相同的向量)。这个例子应该解释不同:
outer(0:5, 0:6, sum) don't work because sum is not "vectorized" (in the sense of returning a vector of the same length as its two arguments). This example should explain the difference:
sum(1:2,2:3) 8 1:2 + 2:3 [1] 3 5
c $ c> sum 使用 mapply 例如:
You can vectorize sum using mapply for example:
identical(outer(0:5, 0:6, function(x,y)mapply(sum,x,y)), outer(0:5, 0:6,'+')) TRUE
PS:通常在使用 outer 我使用 browser 在调试模式下创建我的函数:
PS: Generally before using outer I use browser to create my function in the debug mode:
outer(0:2, 1:3, function(x,y)browser()) Called from: FUN(X, Y, ...) Browse[1]> x [1] 0 1 2 0 1 2 0 1 2 Browse[1]> y [1] 1 1 1 2 2 2 3 3 3 Browse[1]> sum(x,y) [1] 27 ## this give an error Browse[1]> x+y [1] 1 2 3 2 3 4 3 4 5 ## this is vectorized
这篇关于为什么不按我认为应该的方式进行外部工作(在R中)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!