为什么外部工作不像我认为的那样(在 R 中)? [英] Why doesn't outer work the way I think it should (in R)?

查看:21
本文介绍了为什么外部工作不像我认为的那样(在 R 中)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由@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 时不能这样做 函数?

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))

然而,问题仍然存在.术语矢量化"在这里有点含糊,我认为二元"更正确,因为 sincos 在该术语的通常意义上是矢量化"的.期望 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.

这是另一个 outer 错误,可能与我对这个问题缺乏了解有关:

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

您可以使用 mapplysum 进行矢量化,例如:

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 中)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆