Summary:
There are only two ways for R to know that the else clause belongs to the if clause above:
- The entire if ... else statement (and possibly other statements) is enclosed in braces;
- The word else appears on the same line as the end of the if clause.
Proof of:
The above discussion helped me, but I hope I can offer a useful pun. Yes, right, that
f <- function (exp) if (exp) 1 else 2
fails with the classic Error: unexpected 'else' in "else" message due to R's failure to continue reading. 1. Two methods were correctly proposed so that R reads past 1:
f <- function (exp) { if (exp) 1 else 2 }
and
f <- function (exp) if (exp) 1 else 2
But there is a third way that is not mentioned yet --- just move else up the line. So the following also works because R knows what to read in 1:
f <- function (exp) if (exp) 1 else 2
I think the key point is to either copy the entire element of the function, or make sure that else appears on the same line as the end of the if clause, so that R knows what to read. This is why a single line solution works. That is why it works:
f <- function (exp) if (exp) { 1 } else 2
But this fails:
f <- function (exp) if (exp) { 1 } else 2
And using a more standard function body binding, this also works:
f <- function (exp) { if (exp) { 1 } else 2 }
But regardless of whether we are building a function, this is a red herring. The only thing that matters is parentheses and the location of else . Thus, these works:
{ if (exp) { 1 } else 2 } if (exp) { 1 } else 2
but this fails:
if (exp) { 1 } else 2
and to demonstrate my statement 1 at the top, this works:
{ x <- 4 if (exp) 1 else 2 }