How do I remove empty data frames from a list?
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
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]
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