How do I remove empty data frames from a list?

Viewed 16061

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 Answers

Instead of dim(x)[1] you could make use of nrow, so you could do

mlist[sapply(mlist, nrow) > 0]

Filter(function(x) nrow(x) > 0, mlist)

You could also use keep and discard from purrr

purrr::keep(mlist, ~nrow(.) > 0)
purrr::discard(mlist, ~nrow(.) == 0)

There is also compact in purrr which removes all empty elements directly. It is a wrapper on discard

purrr::compact(mlist)

If you are ok to filter the list based on number of columns, you could replace nrow with ncol in above answers. Additionally, you could also use lengths to filter the list.

mlist[lengths(mlist) > 0]

Adding tidyverse option:

library(tidyverse)
mlist[map(mlist, function(x) dim(x)[1]) > 0]


mlist[map(mlist, ~dim(.)[1]) > 0]
Related