Reputation: 4716
Using (preferably) rlist
package, is there a way to filter out nodes of the (multi-level) list, so that the resulting list holds no NA
values on any level?
library(rlist)
devs <-
list(
p1=list(name="Ken",age=24,
interest=c("reading","music","movies"),
lang=list(r=NA,csharp=4)), # <------ NA here
p2=list(name="James",age=25,
interest=c("sports","music"),
lang=list(r=3,java=2,cpp=5)),
p3=list(name="Penny",age=NA, # <------ NA here
interest=c("movies","reading"),
lang=list(r=1,cpp=4,python=2)))
In the above example, since p1
and p3
nodes contain NA
somewhere in their hierarchy, the expected output list should be p2
only. We don't know in advance the structure or names of the input list.
Upvotes: 6
Views: 512
Reputation: 9582
How about:
# for every element in devs, does it have 0 NA elements when unlisted?
sapply(devs, function(x) !anyNA(unlist(x)))
which returns:
p1 p2 p3
FALSE TRUE FALSE
You can get just the desired list element(s) with:
devs[sapply(devs, function(x) !anyNA(unlist(x)))]
Upvotes: 6
Reputation: 4993
list.search()
scans the list recursively on a condition and can be used to find NA
s in child elements of devs
.
Using pipeR
and rlist
together to make the code clearer:
devs %>>%
list.filter(. %>>%
list.search(anyNA(.)) %>>%
length == 0L)
This singles out p2
only.
This is almost a direct translation of your request :)
or an easier way is
list.filter(devs, !anyNA(unlist(.)))
Upvotes: 3