Reputation: 17299
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
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