2011-04-05 15 views
14
> 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] 

¿Por qué does not fun2() funciona? ¿No son fun2() y fun1() esencialmente lo mismo?Pregunta simple sobre el uso de funciones externas() y definidas por el usuario?

+4

No, no son lo mismo. fun1 devuelve la suma de vectores de xey, mientras que fun2 devuelve la suma escalar de los elementos primero y segundo de x e y combinados. – Andrie

Respuesta

7

La respuesta se hace evidente si se lee ?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. 

pensar en lo que está haciendo, usted es concatenando dos vectores en uno vector, después sumar el primer y segundo elementos de este vector . fun1() por otro lado hace la suma vectorizada de las entradas, por lo que el objeto devuelto es de la misma longitud que las longitudes individuales de las entradas. En fun2(), la salida es un vector de longitud 1 y se espera 25.

La manera de hacer que la idea detrás de fun2() trabajo es cbind()noc() las dos entradas:

> 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 
+0

por lo tanto, funciona como el siguiente: 1. a <-expand.grid (seq1, seq2) 2. b <-apply (a, 1, suma) 3.matriz (b, nr = 5) ¿verdad? – colinfang

12

Como alternativa, puede simplemente reemplazar fun2 con Vectorize(fun2) cuando se pasa como argumento a 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)) 
Cuestiones relacionadas