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.
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)
isNaN
. For double inputs, R makes use of IEC 60559 arithmetic on all platforms, together with the C system functionpow
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 commandman pow
gives details of the values in a large number of corner cases.