I'm struggling to understand some R behavior when if/else statements are used implicitly within a function rather than explicitly specifying the expression contained in the if/else statement.
This toy function works as I'd expect it to, printing "x is TRUE"
when handed a TRUE
and printing "x is FALSE"
when handed a FALSE
.
f1 <- function(x){
if (x)
print("x is TRUE")
else
print("x is FALSE")
}
> f1(TRUE)
[1] "x is TRUE"
> f1(FALSE)
[1] "x is FALSE"
>
However, if I add an implicit, nested if statement to it then it stops behaving as I'd expect. The function below was expected to behave exactly as the function above, but instead it prints nothing when handed a FALSE
.
f1 <- function(x){
if (x)
if(TRUE)
print("x is TRUE")
else
print("x is FALSE")
}
> f1(TRUE)
[1] "x is TRUE"
> f1(FALSE) # No output?
>
Finally, if I add brackets to specify the arrangement and make the if/else explicit it functions as expected again:
f1 <- function(x){
if (x){
if (TRUE)
print("x is TRUE")
} else {
print("x is FALSE")
}
}
> f1(TRUE)
[1] "x is TRUE"
> f1(FALSE)
[1] "x is FALSE"
>
In searching for this issue online, I came across two answers vaguely related. One discusses an issue with brackets not working but doesn't discuss different output if the brackets are missing entirely, and the other discusses the famous "Unexpected 'else' in 'else' error. From them, I've come to understand that R is probably interpreting the if
statement as its own line, but I don't understand why there's no error thrown by the unexpected else
within the function or any other output.
Can someone help me understand R's control-flow logic here?
CodePudding user response:
Like many languages, R is greedy about attaching the else
to the nearest if
. So your code is not indented the way R reads it, which is
if (x)
if(TRUE)
print("x is TRUE")
else
print("x is FALSE")
The if(TRUE)
statement gets the else
, and since TRUE
is TRUE
, the else
is never executed.
One oddity in R is that things behave differently if you enter them directly to the console, rather than in a function. Then it is greedy to finish the statement, so what I wrote above would be a syntax error:
if (x)
if(TRUE)
print("x is TRUE")
is a complete statement, so it would be executed. Then when you entered the else
, you'd get an error, because else
is not allowed to start a statement.