Conditional execution using if and else

If? Then! Else?

Sometimes we’ll want R to execute a statement only if a certain condition is met. This can be accomplished via the if() and (optionally) else statements:

if()    # Used to execute a statement only if the given condition
        # is met
else    # Used to specify an alternative statement to be executed 
        # if the condition given in if() isn't met

Such conditional execution commands have the forms:

if (condition) {
  statement1
}

and

if (condition) {
  statement1
} else {
  statement2
}

where condition is a logical expression (i.e. it evaluates to TRUE or FALSE)

In both cases above, if condition is TRUE, statement1 is executed. If condition is FALSE, then in the first case nothing happens, but in the second case, statement2 is executed.

Here’s a simple example:

x <- 5
if (x < 10) {
  y <- 0
}
y
[1] 0

Here’s another:

if (x >= 10) {
  y <- 1
  } else {
    y <- 0
}
y
[1] 0

It is also possible to write short if/else statements on a single line, in that case you do not have to include { }:

y <- if(x >= 10) 1 else 0
y
[1] 0

Be aware that when using such conditional assignment statements, in the absence of else, if() returns NULL if the condition isn’t met. So:

y <- if(x >= 10) 1
y
NULL

Nested if() Statements

In addition, if() statements can be nested. The form for nested if() statements is

if(condition1) {
  if(condition2) {
    statement1 
  } else {
    statement2
  }
}

The else always refers to the most recent if(), but to keep our code readable, we use tab indentation for every level of nesting in our nested if-else statements.

if() else() statements in functions

The (nested) if() else() statements can be used in functions. In the next example, we expand on the earlier function my_descriptives. The function now first checks whether the function is numeric or a factor. For numeric variables, the negative values are removed and the summary statistics provided. For factors, the negative level (-1) is removed and a table of the variable is given.

my_descriptives <- function(x){
  if(class(x) == "numeric"){
    x.trim <- x[x>0]
    summary(x.trim)
  } else if (class(x) == "factor"){
    x.trim <- droplevels(x[x!=-1])
    table(x.trim)
  }
}

The function can now be applied to numeric variables and factors:

my_descriptives(data$Ages)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  26.00   38.50   44.50   44.54   50.25   65.00 
my_descriptives(data$Sex)
x.trim
 0  1 
13 11 

Again, we compare the output with the standard summary() and table() output:

summary(data$Ages)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 -50.00   37.00   43.00   40.76   50.00   65.00 
table(data$Sex)

-1  0  1 
 1 13 11 

Apart form nesting if() statements it is also possible to string multiple if statements together like so:

whatAnimalSound <- function(animal){
  if(animal == "cat") {
    return("Meow!")
  } else if (animal == "frog") {
    return("Ribbit!")
  } else if (animal == "dog") {
    return("Woof!")
  } else {
    return(paste0("I don't know what sound a '",animal,"' makes..."))
  }
}
whatAnimalSound("dog")
[1] "Woof!"
whatAnimalSound("bird")
[1] "I don't know what sound a 'bird' makes..."
Tip

Notice that the last statement can be else, but to string together multiple statements you have to use if else.

Vectorized if-else: The ifelse() Function

Sometimes we’ll need to create a vector whose values depend on whether or not the values in another vector satisfies some condition. In that case we can use the ifelse() function, which works on a vector of values by repeating the same conditional statement for every value in the vector.

ifelse() takes argument test, the condition to be met, yes, the return value (or vector of values) when test is TRUE, and no, the return values (or vector of values) when test is FALSE.

For example, here we convert the values in height to "short" or "tall" based on whether they are larger than 69 or not:

height <- c(69, 71, 67, 66, 72, 71, 61, 65, 73, 70, 68, 74)

htCategory <- ifelse(height > 69, yes = "tall", no = "short")

htCategory
 [1] "short" "tall"  "short" "short" "tall"  "tall"  "short" "short" "tall" 
[10] "tall"  "short" "tall" 

The ifelse function is a very simple way of applying a test to a vector of values. To apply a more complicated function to a vector or to apply a function to multiple rows of a matrix or a dataframe we can use the apply functions which will be discussed later on.