How to generalize outer to n dimensions?

前端 未结 3 1888
独厮守ぢ
独厮守ぢ 2020-12-03 08:58

The standard R expression outer(X, Y, f) evaluates to a matrix whose (i, j)-th entry has the value f(X[i], Y[j]).

I would like to implement

3条回答
  •  庸人自扰
    2020-12-03 09:25

    This is one way: First use Vectorize and outer to define a function that creates an n-dimensional matrix where each entry is a list of arguments on which the given function will be applied:

    list_args <- Vectorize( function(a,b) c( as.list(a), as.list(b) ), 
                            SIMPLIFY = FALSE)
    
    
    make_args_mtx <- function( alist ) {
      Reduce(function(x, y) outer(x, y, list_args), alist)
    }
    

    Now multi.outer just needs to invoke apply and do.call on this "args-matrix" :

    multi.outer <- function(f, ... ) {
      args <- make_args_mtx(list(...))
      apply(args, 1:length(dim(args)), function(a) do.call(f, a[[1]] ) )
    }
    

    Let's try this with an example function:

    fun <- function(a,b,c) paste(a,b,c)
    
    ans <- multi.outer(fun, LETTERS[1:2], c(3, 4, 5), letters[6:7] )
    
    > ans
    , , 1
    
         [,1]    [,2]    [,3]   
    [1,] "A 3 f" "A 4 f" "A 5 f"
    [2,] "B 3 f" "B 4 f" "B 5 f"
    
    , , 2
    
         [,1]    [,2]    [,3]   
    [1,] "A 3 g" "A 4 g" "A 5 g"
    [2,] "B 3 g" "B 4 g" "B 5 g"
    

提交回复
热议问题