Apply family of functions for functions with multi

2019-08-13 01:56发布

问题:

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.

回答1:

(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))


回答2:

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


标签: r apply