Marius Hofert
2011-Jan-29 07:59 UTC
[R] How to apply a two-place function to each combination of elements in two vectors of different lengths?
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... This should be easy but I just don't see it... :-( Cheers, Marius
Petr Savicky
2011-Jan-29 08:34 UTC
[R] How to apply a two-place function to each combination of elements in two vectors of different lengths?
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.
Possibly Parallel Threads
- How to efficiently compare each row in a matrix with each row in another matrix?
- Read data with different column lengths
- How to 'extend' a data.frame based on given variable combinations ?
- How to cbind or rbind different lengths vectors/arrays without repeating the elements of the shorter vectors/arrays ?
- How to apply a function to subsets of a data frame *and* obtain a data frame again?