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.
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)))]
list.search() scans the list recursively on a condition and can be used to find NAs 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(.)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With