There are two primary tools to control the flow of our actions: choices and loops. Choices, like if statements, allow us to execute some code if a condition is fulfilled. Loops, like for and while, allow us to repeatedly run code.

This post discusses the conditional statements.


if

The simplest form of flow control is if conditional statements. if takes a logical value (a logical vector of length one). If the condition is TRUE, the statement gets executed. If the condition is FALSE, if invisibly returns NULL. Most other inputs will generate an error.


How it works:

If we only have one statement:

if(condition) statement

If we have more than one statement, we need to use a pair of curly braces to wrap the statements.

if(condition) {
  statement
}

Example:

x <- sample(1:15, 1) 
x
## [1] 7
if (x > 5) {
  print(paste(x, "is larger than 5."))
}
## [1] "7 is larger than 5."

Or:

x <- sample(1:10, 1) 
x
## [1] 7
if (x > 5) print(paste(x, "is larger than 5."))
## [1] "7 is larger than 5."

ifelse if

If there are other conditions to evaluate, include else if. else if is essentially saying “if the previous condition is not true, then try this condition”.


How it works:

if(condition) {
  statement
} else if (condition) {
  statement
} 

Example:

x <- sample(1:15, 1)
x
## [1] 6
if (x > 5) {
  print(paste(x, "is larger than 5."))
} else if (x < 5) {
  print(paste(x, "is smaller than 5."))
}
## [1] "6 is larger than 5."

We can have more than one else if.

if(condition) {
  statement
} else if (condition) {
  statement
} else if (condition) {
  statement
}

ifelse ifelse

else catches anything that is not caught by the preceding conditions. The else statement is only evaluated if the condition is FALSE.


How it works:

if(condition) {
  statement
} else if (condition) {
  statement
} else {
  statement
}

Example 1:

x <- sample(1:15, 1)
x
## [1] 5
if (x > 5) {
  print(paste(x, "is larger than 5."))
} else if (x == 5) {
  print(paste(x, "is equal to 5."))
} else {
  print(paste(x, "is smaller than 5."))
}
## [1] "5 is equal to 5."

Note: The else statement must occur on the same line as the closing curly brace from the if clause.


Example 2:

Write an R program to convert month name to a number of days. For instance, if we input “February”, then the output will be “No. of days: 28 or 29 days”. Hint: Use readline(), which reads a line from the terminal in interactive use.

month <- as.character(readline("Input a month name: ")
month_30 <- c("April", "June", "September", "November")
month_31 <- c("January", "March", "May", "July", "August", "October", "December")

if (month %in% month_30){
  print("No. of days: 30 days") 
} else if (month %in% month_31){
  print("No. of days: 31 days")
} else if (month == "February") {
  print("No. of days: 28 or 29 days")
} else {
  print("Incorrect input")
}

ifelse

We can have an else statement without the else if.


How it works:

if(condition) {
  true statement
}
else {
  false statement
}

Example:

x <- sample(1:15, 1)
x
## [1] 5
if (x > 5) {
  print(paste(x, "is larger than 5."))
} else {
  print(paste(x, "is not larger than 5."))
}
## [1] "5 is not larger than 5."

Nested if

We can have if statements inside if statements. This is called nested if statements.


Example 1:

x <- sample(1:15, 1)
x
## [1] 9
if (x > 5) {
  print(paste(x, "is larger than 5,"))
  if (x > 10) {
    print(paste("and 10."))
  } else {
    print("but not larger than 10.")
  }
} else {
  print(paste(x, "is not larger than 5"))
}
## [1] "9 is larger than 5,"
## [1] "but not larger than 10."

Example 2:

Write an R program to find the median of three integers. Do not use the built-in function median().

a <- as.integer(readline("Input the 1st number: "))
b <- as.integer(readline("Input the 2nd number: "))
c <- as.integer(readline("Input the 3rd number: "))
if (a > b){
  if (b > c) { print(b) }
  else if (c > a) { print(a) } 
  else { print(c) }
} else {
  if (a > c){ print(a) }
  else if (c > b){ print(b) } 
  else{ print(c) }
} 

Vectorized ifelse()

Remember that if only takes a logical vector of length one. What if we have multiple logical values?

If we pass a logical vector with a length of more than one, e.g. if(c(TRUE, FALSE)), only the first one will be used.

There is a vectorized version of the if ... else construct, the ifelse() function.


How it works:

ifelse(condition, yes, no)

ifelse() takes three arguments. The first is a logical vector of conditions. The second contains values that are returned when the first vector is TRUE. The third contains values that are returned when the first vector is FALSE.

It returns a vector of the same length as condition, with elements yes[i] if condition[i] is TRUE, otherwise no[i]. yes and no are recycled where necessary.


Example:

x <- sample(1:15, 1)
x
## [1] 13
yes <- paste(x, "is larger than 5")
no <- paste(x, "is not larger than 5")
ifelse(x > 5, yes, no)
## [1] "13 is larger than 5"