18
votes

I have a matrix and a function that takes a vector and returns a matrix. I want to apply the function to all rows of the matrix and rbind all results together. For example

mat <- matrix(1:6, ncol=2)
f <- function (x) cbind(1:sum(x), sum(x):1)
do.call(rbind, apply(mat, 1, f))

This works perfectly since the returned matrices have different numbers of rows so apply returns a list. But if they happen to have the same numbers of rows this does not work anymore:

mat <- f(3)
apply(mat, 1, f)

apply returns a matrix from which I cannot get the result I want. Is it possible to force apply to return a list or is there another solution?

2

2 Answers

16
votes

You have to split matrix mat before applying function f.

list_result <- lapply(split(mat,seq(NROW(mat))),f)
matrix_result <- do.call(rbind,list_result)
19
votes

This is why I love the plyr package. It has a number of --ply functions that all work in the same way. The first letter corresponds to what you have as input and the second method corresponds to what you have as output (l for lists, a for arrays, d for data frames).

So the alply() function works similar to apply() but always returns a list:

alply(mat, 1, f)