Question

I would like to use a function from the apply family (in R) to apply a function of two arguments to two matrices. I assume this is possible. Am I correct? Otherwise, it would seem that I have to put the two matrices into one, and redefine my function in terms of the new matrix.

Here's an example of what I'd like to do:

a <- matrix(1:6,nrow = 3,ncol = 2)
b <- matrix(7:12,nrow = 3,ncol = 2)

foo <- function(vec1,vec2){
    d <- sample(vec1,1)
    f <- sample(vec2,1)
    result <- c(d,f)
return(result)
}

I would like to apply foo to a and b.

Was it helpful?

Solution

(Strictly answering the question, not pointing you to a better approach for you particular use here....)

mapply is the function from the *apply family of functions for applying a function while looping through multiple arguments.

So what you want to do here is turn each of your matrices into a list of vectors that hold its rows or columns (you did not specify). There are many ways to do that, I like to use the following function:

split.array.along <- function(X, MARGIN) {
    require(abind)
    lapply(seq_len(dim(X)[MARGIN]), asub, x = X, dims = MARGIN)
}

Then all you have to do is run:

mapply(foo, split.array.along(a, 1),
            split.array.along(b, 1))

Like sapply, mapply tries to put your output into an array if possible. If instead you prefer the output to be a list, add SIMPLIFY = FALSE to the mapply call, or equivalently, use the Map function:

Map(foo, split.array.along(a, 1),
         split.array.along(b, 1))

OTHER TIPS

You could adjust foo to take one argument (a single matrix), and use apply in the function body.
Then you can use lapply on foo to sample from each column of each matrix.

> a <- matrix(1:6,nrow = 3,ncol = 2)
> b <- matrix(7:12,nrow = 3,ncol = 2)

> foo <- function(x){
    apply(x, 2, function(z) sample(z, 1))
  }

> lapply(list(a, b), foo)

## [[1]]
## [1] 1 6

## [[2]]
## [1]  8 12
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top