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 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(.)))
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