[R] How to apply a two-place function to each combination of elements in two vectors of different lengths?

Petr Savicky savicky at praha1.ff.cuni.cz
Sat Jan 29 09:34:53 CET 2011


On Sat, Jan 29, 2011 at 08:59:44AM +0100, Marius Hofert wrote:
> Dear expeRts,
> 
> I somehow can't manage to do the following:
> Given two vectors x and y of lengths 3 and 2, respectively, I would like to apply 
> a function to each combination of the entries of x and y and receive a 3-by-2 matrix
> containing the results. Now outer() seems to be the way to go, but outer() expands
> the vectors first, which leads to errors in my function. Here is the minimal example:
> 
> x <- c(5,6,7)
> y <- c(2,4)
> 
> FUN <- function(x., y.){
>     j <- 1:y.
>     sum(choose(y., j)*choose(0.5*j, x.))
> }
> apply(expand.grid(x, y), 1, FUN=FUN) # that should give at least a vector of length 6, but also fails
> outer(x, y, FUN=FUN) # hmm... I thought/hoped that worked... 

Hello Marius:

According to ?outer

     ‘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.

For apply(), the situation is different, since apply(, 1, FUN) passes
to FUN the rows of its first argument (after coercion to a matrix). So,
FUN in this case should accept a single vector of length 2. Try the
following.

  x <- c(5,6,7)
  y <- c(2,4)
  FUN <- function(x){
      j <- 1:x[2]
      sum(choose(x[2], j)*choose(0.5*j, x[1]))
  }
  apply(expand.grid(x, y), 1, FUN=FUN)

  [1]  0.05468750 -0.04101562  0.03222656  0.06250000 -0.05468750  0.04687500

  matrix(apply(expand.grid(x, y), 1, FUN=FUN), nrow=length(x), ncol=length(y))

              [,1]       [,2]
  [1,]  0.05468750  0.0625000
  [2,] -0.04101562 -0.0546875
  [3,]  0.03222656  0.0468750

Hope this helps.

Petr Savicky.



More information about the R-help mailing list