Search code examples
rmathoperator-precedence

Operator precedence of "unary minus" (-) and exponentiation (^) outside vs. inside function


Why does order of operation [PEMDAS] within functions work right in R?

These work fine:

-27^(1/3) == -3 # TRUE
-27^0.3333333333333333 == -3 # TRUE

But when used inside a function the result is NaN

foo <- function(x, y){return(x^(1/y))}
foo(x = -27, y = 3) # NaN

bar <- function(x, y){
    a = 1 / y
    b = x^a
    return(b)
}

bar(x = -27, y = 3) # NaN

Thanks in advance for the explanation.


Solution

  • Because of the surprisingly low precedence of the "unary minus" (-) operator, combined with R's convention for raising negative numbers to fractional powers. -27^(1/3) is read as "calculate 27^(1/3) (==3), then invert the sign". If we instead compute (-27)^(1/3), we get NaN, because a negative number can't reliably be raised to a fractional power. Whether the evaluation is inside or outside of a function is a red herring; the issue is whether (-27) is evaluated as an expression first (which it is if you assign it to a function argument or a variable, or put it in parentheses).

    The precedence of unary minus is discussed on this mailing list thread from 2009 and R FAQ 7.33, and more generally in this math.stackexchange question. There's a (rather technical) explanation of why a negative value to a fractional power is NaN in ?"^":

    Users are sometimes surprised by the value returned, for example why (-8)^(1/3) is NaN. For double inputs, R makes use of IEC 60559 arithmetic on all platforms, together with the C system function pow for the ^ operator. The relevant standards define the result in many corner cases. In particular, the result in the example above is mandated by the C99 standard. On many Unix-alike systems the command man pow gives details of the values in a large number of corner cases.