Skip to content
Prev 18307 / 63424 Next

unvectorized option for outer()

[following on from a thread on R-help, but my post here seems more 
appropriate to R-devel]

Would a patch to make outer() work with non-vectorized functions be
considered?  It seems to come up moderately often on the list, which
probably indicates that many many people get bitten by the same
incorrect expectation, despite the documentation and the FAQ entry.  It
looks pretty simple to modify outer() appropriately: one extra function
argument and an if-then-else clause to call mapply(FUN, ...) instead of
calling FUN directly.

Here's a function demonstrating this:

outer2 <- function (X, Y, FUN = "*", ..., VECTORIZED=TRUE)
{
     no.nx <- is.null(nx <- dimnames(X <- as.array(X)))
     dX <- dim(X)
     no.ny <- is.null(ny <- dimnames(Y <- as.array(Y)))
     dY <- dim(Y)
     if (is.character(FUN) && FUN == "*") {
         robj <- as.vector(X) %*% t(as.vector(Y))
         dim(robj) <- c(dX, dY)
     }
     else {
         FUN <- match.fun(FUN)
         Y <- rep(Y, rep.int(length(X), length(Y)))
         if (length(X) > 0)
             X <- rep(X, times = ceiling(length(Y)/length(X)))
         if (VECTORIZED)
             robj <- FUN(X, Y, ...)
         else
             robj <- mapply(FUN, X, Y, MoreArgs=list(...))
         dim(robj) <- c(dX, dY)
     }
     if (no.nx)
         nx <- vector("list", length(dX))
     else if (no.ny)
         ny <- vector("list", length(dY))
     if (!(no.nx && no.ny))
         dimnames(robj) <- c(nx, ny)
     robj
}
# Some examples
f <- function(x, y, p=1) {cat("in f\n"); (x*y)^p}
outer2(1:2, 3:5, f, 2)
outer2(numeric(0), 3:5, f, 2)
outer2(1:2, numeric(0), f, 2)
outer2(1:2, 3:5, f, 2, VECTORIZED=F)
outer2(numeric(0), 3:5, f, 2, VECTORIZED=F)
outer2(1:2, numeric(0), f, 2, VECTORIZED=F)

# Output on examples
in f
      [,1] [,2] [,3]
[1,]    9   16   25
[2,]   36   64  100
in f
      [,1] [,2] [,3]
in f

[1,]
[2,]
in f
in f
in f
in f
in f
in f
      [,1] [,2] [,3]
[1,]    9   16   25
[2,]   36   64  100
[,1] [,2] [,3]
[1,]
[2,]
If a patch to add this feature would be considered, I'd be happy to
submit one (including documentation).  If so, and if there are any
potential traps I should bear in mind, please let me know!

-- Tony Plate
Rau, Roland wrote: