Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force apply to return a list

Tags:

r

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?

like image 789
mosaic Avatar asked Jun 05 '11 05:06

mosaic


People also ask

Does mApply return a list?

For mApply , the returned value is a vector, matrix, or list.

Why is Sapply returning a list?

The real reason for this is that sapply doesn't know what your function will return without calling it. In your case the function returns a logical , but since sapply is given an empty list, the function is never called. Therefore, it has to come up with a type and it defaults to list .


2 Answers

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)
like image 97
Sacha Epskamp Avatar answered Oct 21 '22 07:10

Sacha Epskamp


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)
like image 35
Wojciech Sobala Avatar answered Oct 21 '22 09:10

Wojciech Sobala