Простой вопрос об использовании внешних() и пользовательских функций?

> fun1 <- function(x,y){x+y}
> outer(seq(1,5,length=5),seq(6,10,length=5),fun1)
     [,1] [,2] [,3] [,4] [,5]
[1,]    7    8    9   10   11
[2,]    8    9   10   11   12
[3,]    9   10   11   12   13
[4,]   10   11   12   13   14
[5,]   11   12   13   14   15
> fun2 <- function(x,y){z<-c(x,y);z[1]+z[2]}
> outer(seq(1,5,length=5),seq(6,10,length=5),fun2)
Error in dim(robj) <- c(dX, dY) : 
  dims [product 25] do not match the length of object [1]

Почему не работает fun2()? Не являются ли fun2() и fun1() по существу одной и той же?

Ответы

Ответ 1

Ответ становится очевидным, если вы читаете ?outer:

Details:

     ‘X’ and ‘Y’ must be suitable arguments for ‘FUN’.  Each will be
     extended by ‘rep’ to length the products of the lengths of ‘X’ and
     ‘Y’ before ‘FUN’ is called.

     ‘FUN’ is called with these two extended vectors as arguments.
     Therefore, it must be a vectorized function (or the name of one),
     expecting at least two arguments.

Подумайте, что вы делаете, вы конкатенируете два вектора в один вектор, затем суммируете первый и второй элементы этого вектора. fun1(), с другой стороны, представляет собой векторизованную сумму входов, поэтому возвращаемый объект имеет такую ​​же длину, как и отдельные длины входов. В fun2() выход представляет собой вектор длины 1, и он ожидал 25.

Способ построения fun2() заключается в cbind() not c() двух входах:

> fun3 <- function(x, y) { z <- cbind(x, y); z[,1] + z[,2]}
> outer(seq(1,5,length=5),seq(6,10,length=5),fun3)
     [,1] [,2] [,3] [,4] [,5]
[1,]    7    8    9   10   11
[2,]    8    9   10   11   12
[3,]    9   10   11   12   13
[4,]   10   11   12   13   14
[5,]   11   12   13   14   15

Ответ 2

В качестве альтернативы вы можете просто заменить fun2 на Vectorize(fun2), передав его как аргумент outer:

fun2 <- function(x,y){z<-c(x,y);z[1]+z[2]}
outer(seq(1,5,length=5),seq(6,10,length=5), Vectorize(fun2))