3

I have three expressions, each involving multiplication with a logical or its negation. These logicals and their negation represent indicator variables, so that the expressions are conditionally evaluated:

-2*3*!T + 5*7*T
5*7*T + -2*3*!T 
(-2*3*!T) + 5*7*T

I expect the above to produce the same result. However:

> -2*3*!T + 5*7*T
[1] 0          # unexpected!
> 5*7*T + -2*3*!T 
[1] 35
> (-2*3*!T) + 5*7*T
[1] 35

I am sure this has something to do with operator precedence and type coercion, but I can't work out how it makes sense to even evaluate !T after the *.

Alex
  • 15,186
  • 15
  • 73
  • 127
  • Almost certainly an issue with `!` as `-2*3*(!T) + 5*7*T` works too. – thelatemail Nov 01 '16 at 23:46
  • 2
    Thanks, it looks like best practice would be to enclose the negations in brackets first in such expressions. – Alex Nov 01 '16 at 23:56
  • 3
    Also relevant - http://stackoverflow.com/questions/17651687/behavior-of-summing-is-na-results Which suggests also looking at `codetools::showTree(quote( -2*3*(!T) + 5*7*T ))` vs. `codetools::showTree(quote( -2*3*!T + 5*7*T ))` if you're familiar with Lisp code. – thelatemail Nov 01 '16 at 23:57
  • Thanks. That was exactly what I was looking for, I just didn't know how to look for it. – Alex Nov 02 '16 at 00:01
  • 1
    The votes-to-close are wrong; this is a good and clear question. R's logical-not operator does indeed have a precedence bug, we all learn the hard way. When I hit it (in a compound expression), it cost me >10 hours of head-scratching. – smci Nov 02 '16 at 12:04
  • 1
    @smci, thanks. Unfortunately sometimes it is just not possible to make anyone see reason, at any time ;) – Alex Nov 03 '16 at 03:07
  • @Alex, we try to put the 'R' into reason... or is that the other way around? – smci Nov 03 '16 at 06:39

1 Answers1

4

You're exactly right that this is about operator precedence. As ?base::Syntax (which you link above) states, ! has lower precedence than all of the arithmetic operators, so the first expression is equivalent to

(-2*3)*!(T + 5*7*T)  

(because the expression containing ! has to be evaluated before the final multiplication can be done) or

-6*!(36)  # T coerced to 1 in numeric operations

or

-6*FALSE  # non-zero numbers coerced to TRUE in logical operations

or

-6*0      # FALSE coerced to 0 in numeric operations
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453