Reputation: 202
I have a list of lists, which may contain NA values. How can I remove the lists that are full of NA values, keeping in mind that if there are non-NA values on the list these values and the NA values should not be removed?
An input example:
myList <- list()
myList[[1]] <- c(1,2,3)
myList[[2]] <- c(4,5)
myList[[3]] <- c(NA,NA,NA,NA,NA)
myList[[4]] <- c(NA, 6, 7, NA)
myList[[5]] <- NA
The desired output is:
[[1]]
[1] 1 2 3
[[2]]
[1] 4 5
[[3]]
[1] NA 6 7 NA
So far I was able to do:
test <- lapply(myList, function(x) x[!all(is.na(x))])
and got as output:
[[1]]
[1] 1 2 3
[[2]]
[1] 4 5
[[3]]
logical(0)
[[4]]
[1] NA 6 7 NA
[[5]]
logical(0)
Upvotes: 7
Views: 1664
Reputation: 11480
You can "kill" elements by assigning NULL
to it.
myList[sapply(myList,function(x) all(is.na(x)))] <- NULL
Upvotes: 0
Reputation: 93813
Filter
to the rescue:
Filter(function(x) !all(is.na(x)), myList)
#[[1]]
#[1] 1 2 3
#
#[[2]]
#[1] 4 5
#
#[[3]]
#[1] NA 6 7 NA
Upvotes: 5
Reputation: 887028
Another option is discard
library(purrr)
discard(myList, ~ all(is.na(.x)))
#[1]]
#[1] 1 2 3
#[[2]]
#[1] 4 5
#[[3]]
#[1] NA 6 7 NA
Upvotes: 5
Reputation: 17289
You could subset list elements with at least one non NA value:
> myList[sapply(myList, function(x) sum(!is.na(x))) > 0]
[[1]]
[1] 1 2 3
[[2]]
[1] 4 5
[[3]]
[1] NA 6 7 NA
Upvotes: 4