tags:

views:

80

answers:

2

I've got dozens of lists, each is a collection of 11 data frames. Some data frames are empty (another script did not output any data, not a bug).

I need to push each list through a function but that chokes when it sees an empty data frame. So how do I write a function that will take a list, do a dim on each element (i.e. data frame) and if it's 0, then skip to the next.

I tried something like this:

empties <- function (mlist)
{
 for(i in 1:length(mlist))
   {
    if(dim(mlist[[i]])[1]!=0) return (mlist[[i]])
    }
}

But clearly, that didn't work. I would do this manually at this point but that would take forever. Help?

+4  A: 

I'm not sure if this is exactly what you're asking for, but if you want to trim mlist down to contain only non-empty data frames before running the function on it, try mlist[sapply(mlist, function(x) dim(x)[1]) > 0].

E.g.:

R> M1 <- data.frame(matrix(1:4, nrow = 2, ncol = 2))
R> M2 <- data.frame(matrix(nrow = 0, ncol = 0))
R> M3 <- data.frame(matrix(9:12, nrow = 2, ncol = 2))
R> mlist <- list(M1, M2, M3)
R> mlist[sapply(mlist, function(x) dim(x)[1]) > 0]
[[1]]
  X1 X2
1  1  3
2  2  4

[[2]]
  X1 X2
1  9 11
2 10 12
brentonk
Exactly what I wanted. Thanks so much!
Maiasaura
I was also using lapply which I didn't realize returns the same length...
Maiasaura
+2  A: 

A slightly simpler and more transparent approach to the sapply/indexing combination is to use the Filter() function:

> Filter(function(x) dim(x)[1] > 0, mlist)
[[1]]
  X1 X2
1  1  3
2  2  4

[[2]]
  X1 X2
1  9 11
2 10 12
Harlan