mt1022
mt1022

Reputation: 17299

Why the RHS got evaluated when the LHS is FALSE for and operation in R?

I was expecting that for "and" operations RHS expression will not be evaluated if the LHS expression is evaluated to FALSE.

However, while this (1) works fine:

'xxx' %in% names(mtcars) & all(mtcars$xxx > 0)
# [1] FALSE

This one (2) gives a warnings:

'xxx' %in% names(mtcars) & sum(!is.na(mtcars$xxx)) > 0
# [1] FALSE
# Warning message:
# In is.na(mtcars$xxx) :
#   is.na() applied to non-(list or vector) of type 'NULL'

Clearly, this error suggest that the RHS of above line is evaluated. As 'xxx' %in% names(mtcars) is FALSE, why sum(!is.na(mtcars$xxx)) > 0 got evaluated? And why there is no warning whith the first one?

Upvotes: 1

Views: 341

Answers (1)

Dason
Dason

Reputation: 61953

You need the && operator to short-circuit.

> FALSE & stop("hey")
Error: hey
> FALSE && stop("hey")
[1] FALSE

From ?'&':

& and && indicate logical AND and | and || indicate logical OR. The shorter form performs elementwise comparisons in much the same way as arithmetic operators. The longer form evaluates left to right examining only the first element of each vector. Evaluation proceeds only until the result is determined. The longer form is appropriate for programming control-flow and typically preferred in if clauses.

As to why the first didn't creating an error/warning... it's because there isn't anything to give a warning about. We can take it step by step to see what happens.

> mtcars$xxx
NULL
> NULL > 0
logical(0)
> all(logical(0))
[1] TRUE

Note that the last part is perfectly in line with the documentation. From ?all:

The value returned is TRUE if all of the values in x are TRUE (including if there are no values)

Upvotes: 2

Related Questions