[R] outer function problems

Thomas Lumley tlumley at u.washington.edu
Tue Oct 28 20:15:17 CET 2003


On Tue, 28 Oct 2003, Scott Norton wrote:

> Thanks Spencer and Tom for your help!
>
>       Besides the other errors, I realized last night that I'm making a
> fundmental error in my interpretation of the outer function.  The following
> short code snippet highlights my confusion.
>
> f<-function(A,B) { sum(A+B) }
> outer(1:3,2:4,f)
>      [,1] [,2] [,3]
> [1,]   45   45   45
> [2,]   45   45   45
> [3,]   45   45   45
>
> I had *thought* that outer() would give:
>      [,1] [,2] [,3]
> [1,]   3     4    5
> [2,]   4     5    6
> [3,]   5     6    7

This is actually a FAQ


> ie. take each combination from A = 1,2,3; B=2,3,4 such as A=1,B=2 put it in
> the sum function, get [1,1]=3 ...
> Then grab A[2]=2,B[1]=2, put them in the sum() function to get [2,1]=4,
> etc... That "seems" to be the way the instructions explain "outer", i.e.
> element-by-element computation of FUN()
> "Description:
>
>      The outer product of the arrays 'X' and 'Y' is the array 'A' with
>      dimension 'c(dim(X), dim(Y))' where element 'A[c(arrayindex.x,
>      arrayindex.y)] = FUN(X[arrayindex.x], Y[arrayindex.y], ...)'."
>
> Since my interpretation is *definitely* wrong, could someone put in words
> how "OUTER" handles the argument vectors and the functional call with
> reference to the preceding example?

As the description says, outer() constructs *one* call to FUN, replicating
all the arguments.

As the Details section says
     'FUN' must be a function (or the name of it) which expects at
     least two arguments and which operates elementwise on arrays.

Your function f() doesn't.


> Also, what I need to happen in my code is to actually take each combination
> of elements from vectors, A and B, and "feed" them repeatedly into a
> function, generating a matrix of results.  How then do I do that?

One general-purpose way is to use mapply

outer(a,b, function(ai,bj) mapply(f,ai,bj))

The reason this isn't the default is that it is fairly slow.  If your
function f() can be vectorised then that will give much better
performance. For example, compare
  outer(a,b, function(ai,bj) mapply(sum,ai,bj))
and
  outer(a,b, "+")
on largish a and b.

An automatic solution *has to* use a loop, and length(a)*length(b)
evaluations of the function.

	-thomas




More information about the R-help mailing list