Search code examples
rtypechecking

Applying is.logical to a list with multiple data types


I'm trying to figure out how to do some data quality checking on a code.

Suppose I have

x <- list(1,2,T)
y <- list(1,2,3)

I want to be able to apply a function which will flag 'x' as having bad data.

if(any(is.logical(x))) stop('Bad data')

but

if(any(is.logical(y)))

won't trigger an error.

I know I could do it with a for loop, but I'm hoping to find a simpler solution.

For Loop Solution

for (tmp in x) {if (is.logical(tmp)) stop('Bad data')}

Solution

  • solution is to use sapply.

    > any(sapply(x,is.logical))
    [1] TRUE
    
    > any(sapply(y,is.logical))
    [1] FALSE 
    

    Note that using any and sapply is significantly slower than using a for loop.

    > system.time(any(sapply(x,is.logical)))
      user  system elapsed 
      1.58    0.02    1.61 
    
    > system.time(for (blah in x) {if(is.logical(x)) {}})
      user  system elapsed 
      0.29    0.00    0.29
    

    Using vapply as suggested below

    > system.time(any(vapply(x, is.logical, logical(1))))
      user  system elapsed 
      0.30    0.01    0.28