Home > OS >  Implicit vs explicit if/else in R, brackets change output?
Implicit vs explicit if/else in R, brackets change output?

Time:09-17

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.

  • Related