Reputation: 87
I have a list of 12 matrices called M
and I'm trying to remove every matrix from the list that has 0 rows.
I know that I can manually remove those matrices with (for example, to remove the second matrix) M[2] <- NULL
. I would like to use logic to remove them with something like: M <- M[nrow(M)>0,]
(but that obviously didn't work).
Upvotes: 7
Views: 661
Reputation:
Another option worth mentioning with purrr
is keep()
, discard()
, or compact()
. The package purrr
is my go-to these days with lists.
library(purrr)
# simplest by far
compact(M)
# probably a bit easier to remember what you did later
keep(M, ~ nrow(.) > 0)
discard(M, ~ nrow(.) == 0)
Upvotes: 0
Reputation: 2250
I think @Akrun has the cleanest answer. I made this up before I saw his. It is reproducible and also explains a different way of going about it that I used with out thinking about more elegant solutions.
# create list of matrices
matrixlist <- list(matrix(nrow=4,ncol=4,1),
matrix(nrow=4,ncol=4,1),
matrix(nrow=0,ncol=4,1),
matrix(nrow=4,ncol=4,1))
matrixlist
# Identify matrices in my list that have at least one row
idx <- lapply(lapply(matrixlist, `[`), nrow) > 0
# subset the original list with this criteria
my_revised_matrixlist <- matrixlist[idx]
my_revised_matrixlist
All this was accomplished by Akrun's simple Filter(nrow, matrixlist)
Upvotes: 2
Reputation: 887501
Another option that could work is Filter
in base R
Filter(nrow, M)
It works because 0 is considered as FALSE and all other values as TRUE
If there are also some attributes, gv
from collapse
could maintain it
library(collapse)
gv(M, function(x) nrow(x) > 0)
Upvotes: 7
Reputation: 76555
Here is a one-liner.
M <- M[sapply(M, nrow) != 0]
M <- lapply(1:5, function(n){
if(n %% 2 == 0)
matrix(nrow = 0, ncol = 2)
else
matrix(1:4, nrow = 2)
})
Upvotes: 3
Reputation: 226532
Use sapply()
to get a logical vector of non-zero matrices, then use that vector to select/subset:
nzm <- sapply(M, function(m) nrow(m)>0)
M <- M[nzm]
Upvotes: 5