Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force mapply to return a list?

Tags:

Suppose I have a function that creates data frames. I'd like to run that function with different input values, and then rbind the results together into one big data frame, as below:

CreateDataFrame <- function(type="A", n=10, n.true=8) {
  data.frame(success=c(rep(TRUE, n.true), rep(FALSE, n - n.true)), type=type)
}
df <- do.call(rbind, lapply(toupper(letters[1:5]), CreateDataFrame))

My CreateDataFrame function takes three arguments. In the example above, the second and third arguments are held constant. I'd like to do the same as above, but have the second and third arguments change on each call. I think I have to use mapply, like this:

mapply("CreateDataFrame", type=toupper(letters[1:5]), n=10, n.true=8:4)

I'm having trouble because mapply isn't returning a list, which prevents me from running do.call(rbind, mapply(...)). How can I end up with a single data frame, as I did in the example at the top?

Looks like mapply is returning a matrix of lists. I was expecting it to return a list of data frames. What should I do differently?

like image 873
Adrian Avatar asked Jan 04 '12 20:01

Adrian


People also ask

Does Mapply return a list?

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

What does Mapply return in R?

Return value The mapply() function returns a list or if the argument, SIMPLICITY = TRUE , a vector, array, or list.

What is Mapply?

mapply is a multivariate version of sapply . mapply applies FUN to the first elements of each ... argument, the second elements, the third elements, and so on. Arguments are recycled if necessary.


2 Answers

To get a list of data.frames as the return value, set mapply's SIMPLIFY argument to FALSE. (Its default value is TRUE, which directs the function to "attempt to reduce the result to a vector, matrix or higher dimensional array" -- just what you experienced).

res <- mapply("CreateDataFrame", type=toupper(letters[1:5]), n=10, n.true=8:4, 
              SIMPLIFY = FALSE)

identical(class(res), "list")
[1] TRUE
like image 158
Josh O'Brien Avatar answered Sep 20 '22 15:09

Josh O'Brien


Alternative you can use the Map function. It is basically mapply with SIMPLIFY set to FALSE.

Map("CreateDataFrame", type=toupper(letters[1:5]), n=10, n.true=8:4)
like image 31
Wolfgang Wu Avatar answered Sep 18 '22 15:09

Wolfgang Wu