jpsmith
jpsmith

Reputation: 17646

Issue with sapply when determining if nested list has all NA values in R

I have a nested list (or list of lists) with NA randomly allocated values. I am trying to determine if the nested list contains all NA values. For example:

#Example list with NA values
L.miss<-list(list(NA,NA,c(NA,NA,NA),c(NA,NA)),list(1,6,c(0,3,NA,0,NA,0),c(0,NA,0,1,0,0),1,NA,c(0,1),2,c(0,0)),
             list(NA,NA),list(1,0),list(1,NA,c(NA,0,0,0),c(NA,NA),c(1,0,0,NA,0),0))

Here, L.miss[[1]] and L.miss[[3]] contain all NA values. When I try:

all.NA<-sapply(L.miss, function(x) all(is.na(x)))

it returns a logical vector [1] FALSE FALSE TRUE FALSE FALSE. The desired output would be [1] TRUE FALSE TRUE FALSE FALSE since positions L.miss[[1]] and L.miss[[3]] contain vectors of all NA. I have tried lapply and rapply in the same function but does not work, and an exhaustive internet search doesn't provide much help. I am not sure why it is picking up the [[3]] position and not the [[1]] position. Any advice would be appreciated!

Upvotes: 6

Views: 488

Answers (3)

BroVic
BroVic

Reputation: 1079

According to ?is.na:

The default methods also work for lists and pairlists: For 'is.na', elementwise the result is false unless that element is a length-one atomic vector and the single element of that vector is regarded as 'NA' or 'NaN' (note that any 'is.na' method for the class of the element is ignored). 'anyNA(recursive = FALSE)' works the same way as 'is.na'; 'anyNA(recursive = TRUE)' applies 'anyNA' (with method dispatch) to each element

So, the element c(NA, NA) of your list will always return FALSE. To achieve your desired result, you need to apply is.na to each element of the nested atomic vector. .

Upvotes: 0

SmokeyShakers
SmokeyShakers

Reputation: 3402

unlist the nested lists, then test:

all.NA<-sapply(L.miss, function(x) all(is.na(unlist(x))))

Upvotes: 5

Fino
Fino

Reputation: 1784

You need to apply all(is.na()) to the nested lists:

all.NA <- sapply(L.miss, function(x) all(sapply(x, function(y) all(is.na(y)))))

Upvotes: 4

Related Questions