Why is my logical && comparison producing NA?

Who knew? I thought the difference between & and && for ANDing logical vectors in R was just that & evaluated the whole expression while && started at the left and went right until it hit a FALSE value. But there’s more. & is vectorized, but && only considers the first value in a vector and only returns a single value.

Here’s what happens when you use &&:

> c(T,F) && c(T,F)  # trailing F on both sides
[1] TRUE
> c(F,T) && c(T,T)  # a leading F on right
[1] FALSE
> c(T,T) && c(F,T)  # a leading F on left
[1] FALSE

On the other hand, here’s &:

> c(T,F) & c(T,F)
[1] TRUE FALSE      # & returns a vector of values
> c(F,T) & c(T,T)
[1] FALSE TRUE      # comparing pairs by position
> c(T,T) & c(F,T)
[1] FALSE TRUE      # ie, [1] to [1], [2] to [2], etc.

So, unless you knew that && isn’t vectorized, you’d get pretty frustrated that code like this doesn’t work…

p <- df$TY=="JOUR" && nchar(df$SN)==8

I did this and expected p to be a logical TRUE-FALSE vector the same length as the columns in my dataframe. When I examined it, however, p looked like this:

p[1:10]
[1] TRUE NA NA NA NA NA NA NA NA NA

I spent an embarrassing-long time trying to figure out where those NAs were coming from. But then I gave  & a try instead of && (not expecting it to make any difference!) and my upside-down world turned rightside-up again.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.