Reputation: 4114
It appears that the logical NOT operator !
has non-intuitive order of operations in arithemtic:
set.seed(42)
a <- sample(100, 3)
b <- sample(100, 3)
c <- sample(100, 3)
l <- (1:3) <= 2
a * !l - b * !l + c
# 0 0 29
# same expression, but with parentheses for explicit grouping order of operations
(a * !l) - (b * !l) + c
# 74 14 43
There must be something I do not understand about the !
operator in relation to *
or conversion from logical to numeric?
Upvotes: 3
Views: 341
Reputation: 206486
Note that in R, the negation operator !
will apply to entire expression to the right of the operator until it gets to the end or encounters an expression with a lower precedence. It does not just negate the most immediate term. Recall also that 0 is treated as FALSE and any other number is TRUE. So observe
!0
# [1] TRUE
!5
# [1] FALSE
!5-5
# [1] TRUE
!5-3-2
# [1] TRUE
(!5)-3-2
# [1] -5
So you see in the case of !5-3-2
the negation isn't happening until after the 5-3-2 is evaluated. Without the parenthesis, the negation is the very last thing that happens.
So when you write
a * !l - b * !l + c
that's the same as
a * !(l - (b * !(l + c)))
Because all the operations have to happen to the right of the negation before the negation can occur.
If you want to negate just the l
terms, you can do
a * (!l) - b * (!l) + c
This is a function of the operator precedence in R (see the ?Syntax
help page for details). It's once of the last operators to be evaluated in the given expression.
Note that &
and |
have a lower precedence than !
so when you do
!a | !b & !c
that's the same as
(!a) | ((!b) & (!c))
so this roughly would be what you expect if you just stick to logical operators. It just gets a bit odd perhaps when you combine logical and arithmetic operators.
Upvotes: 3