Chapter 2 Logical Expressions and If-Else Statements in R

2.1 Logical Expression in R

  • A Logical expression is an expression that evaluates to either TRUE or FALSE.

  • The following are examples of logical expressions in R:

    • 4 > 2
    • 3 <= 5
    • 15.0 + 1.3*1.3 > 17.0
    • "cat" == "dog"
  • Each of the above expressions will evaluate to either TRUE or FALSE if you run them in R.

4 > 2
## [1] TRUE
3 <= 5
## [1] TRUE
15.0 + 1.3*1.3 > 17.0
## [1] FALSE
x <- "cat" == "dog" # assign to the variable x the value 
                    # returned by this logical expression
x
## [1] FALSE

  • Most logical expressions are constructed by using some combination of:
    • Comparison operators (<, <=, ==, !=)
    • Logical operators (and, or, not) (in R: &&, ||, !)

2.1.1 Comparison Operators

Operator Meaning Example Result
< Less than 5 < 3 FALSE
> Greater than 5 > 3 TRUE
<= Less than or equal to 3 <= 6 TRUE
>= Greater than or equal to 4 >= 3 TRUE
== Equal to 2 == 2 TRUE
!= Not equal to ‘str’ != ‘stR’ TRUE

2.1.2 Logical Operators

  • The first main logical operator we will discuss is the logical AND

  • In R, the logical operator & is used to represent the logical AND

  • The logical AND is used to test whether or not two statements are both true.

  • For two logical expressions A and B, the logical expression A & B is true only if both A and B evaluate to true.

4 > 2 & 5/2 == 1   ## only the first statement is TRUE
## [1] FALSE
4 > 2 & "car" == "truck"   ## only the first statement is TRUE
## [1] FALSE
4 > 2 & 3 < 5   ## both statements are TRUE
## [1] TRUE

  • The logical operator | is used in R to represent the logical OR.

  • For two Boolean expressions A and B, the Boolean expression A | B is true if at least one of A and B evaluates to true.

  • Note that if A and B are both true, A | B will be true; or does not mean only one of A and B is true.

4 > 2 | 5/2 == 1  ## only the first statement is TRUE
## [1] TRUE
4 > 2 | "car" == "truck"  ## only the first statement is TRUE
## [1] TRUE
4 > 2 | 3 < 5  ## both statements are TRUE
## [1] TRUE

  • The logical operator ! is used to represent the logical NOT.

  • If the logical expression A is true, then ! A is false.

!4 > 2  
## [1] FALSE
!4 > 2 & 3 > 1  ## !4 > 2 is FALSE
## [1] FALSE
!(!4 > 2 & !3 > 1) ## expression in parentheses is evaluated first
## [1] TRUE

  • Note that we can apply logical operations to the keywords TRUE and FALSE themselves:
TRUE & FALSE ## logical AND
## [1] FALSE
TRUE | FALSE ## logical OR
## [1] TRUE
!TRUE  ## logical NOT
## [1] FALSE
  • The below table summarizes the logical operations discussed.
Operator Meaning Example Result
! Logical NOT !TRUE FALSE
!FALSE TRUE
&& Logical AND FALSE & FALSE FALSE
TRUE & FALSE FALSE
FALSE & TRUE FALSE
TRUE & TRUE TRUE
|| Logical OR FALSE | FALSE FALSE
TRUE | FALSE TRUE
FALSE | TRUE TRUE
TRUE | TRUE TRUE

2.1.3 Precedence with logical operations

Operators Meaning Precedence
&, |, ! Boolean operators Low
+, - Addition and subtraction
*, /, %% Multiplication, division, remainder
**, ^ Exponentiation
(expressions …) Parenthesis High
  • Mathematical operations are generally performed before logical operations.
4 + 2 > 5
## [1] TRUE
4 + 2 == 6
## [1] TRUE

2.1.4 Abbreviating TRUE and FALSE with T and F

  • You can use T and F in place of TRUE and FALSE
    • I usually do not use T and F, but you will often see T and F used.
T     ## T is shorthand for TRUE
## [1] TRUE
F     ## F is shorthand for FALSE
## [1] FALSE
T && F
## [1] FALSE
T || F
## [1] TRUE
  • While you can use T and F in place of TRUE and FALSE, it is good practice to be careful when using these logical abbreviations.
T <- 2   ## T is defined as a variable

          ## Now T represents a vector with 
T         ## a number value, not TRUE
## [1] 2
F        ## F still represents FALSE
## [1] FALSE
## FALSE <- 3   # this will result in an error

## TRUE and FALSE cannot be redefined, thus safer to use

2.1.5 Examples of logical operations in R

TRUE | FALSE  ## boolean OR
## [1] TRUE
!TRUE          ## NOT operator
## [1] FALSE
!TRUE | TRUE    ## Which one will get evaluated first?
## [1] TRUE
! (TRUE | TRUE) ## How about this time?
## [1] FALSE

2.1.6 logical operators and vectors

  • You can also apply the logical operators &, |, ! to two vectors.

  • As an example, let us first define two logical vectors x and y of length 4

x <- c(TRUE, FALSE, TRUE, FALSE)
y <- c(TRUE, TRUE, FALSE, FALSE)
x
## [1]  TRUE FALSE  TRUE FALSE
y
## [1]  TRUE  TRUE FALSE FALSE
  • Applying the logical operator & to x and y will apply an element-by-element logical and to the elements of x and y.

  • That is, running x & y will return the following result

x & y  ## & returns a vector comparing element-by-element
  • Similarly, applying the logical operator | to x and y will apply an element-by-element logical or to the elements of x and y.
x | y  ## | returns a vector comparing element-by-element
  • Using the logical operator ! with a vector will just return a vector where the TRUE values have been switched to FALSE and the FALSE values have been switched to TRUE:
!x
## [1] FALSE  TRUE FALSE  TRUE

2.1.7 && vs. & and || vs. |

  • I would suggest using & for the logical AND operator and | for the logical OR operator.

  • You may sometimes see && and || being used in R code.

  • && and || can only be used for comparing vectors of length 1.

    • For vectors of length 1, they do the exact same thing as & and |
  • For example,

TRUE & FALSE  ## Same as TRUE && FALSE
## [1] FALSE
TRUE && FALSE  
## [1] FALSE
TRUE | FALSE  ## Same as TRUE || FALSE
## [1] TRUE
TRUE || FALSE  
## [1] TRUE

2.2 If and If-else statements

2.2.1 if statements

  • In R, the form of an if statement is the following:
if( condition ) {
    code_chunk1
}
  • condition is usually a logical expression, but could just be a logical vector of length 1 (i.e., TRUE or FALSE).

  • If condition evaluates to TRUE, code_chunk1 will be executed.

  • You actually do not have to indent the code in code_chunk1, but I would recommend that you do indent.

  • The code inside {…} will be executed only if the condition of the if statement is TRUE.

if (TRUE) { # if condition is TRUE 
  "hello"   # this statement will run
}
## [1] "hello"
if (FALSE) { # if condition is FALSE 
  "world"   # this statement will NOT run
}

2.2.2 if statement examples

  • Example 1: Running the following code will output the message in the if statement because the logical expression x < y evalutes to TRUE
x <- 1
y <- 2
if (x < y ) {
  "x is smaller than y"
}
## [1] "x is smaller than y"
  • Example 2: Running the following code will not print out anything:
x <- 1
y <- 2
if (x > y ) {
  "x is greater than y"
}
  • Example 3:
x <- 3
y <- 2
if (x < y ) {
  "x is smaller than y"
}

if (x > y ) {
  "x is greater than y"
}
## [1] "x is greater than y"
  • Example 4:
if( 2 < 3 ) {
    "Hello"
}
## [1] "Hello"
  • Example 5:
if( "dog" == "cat" ) {
    "Hello"
}
  • Example 6:
d = 2
if( d < 3 && d == 2.5) {
    "Hello"
}
  • Example 7:
if( 2 < 3 || 2 == 2.5) {
    "Hello"
}
## [1] "Hello"

2.2.3 Single-line if statements

  • If the code to be executed in the if statement is short, you can write it immediately after if(condition) on the same line.

  • Or, you can write the single-line statement on the line immediately below if(condition)

x = 5
if(x > 4 & TRUE) x = 2*x # multiply x by 2
x
## [1] 10
  • This single-line if statement is the same as using:
x = 5
if(x > 4 & TRUE) { 
    x = 2*x # multiply x by 2
}
x
## [1] 10

2.3 if-else statements

  • In many cases, you want to perform an action if a condition is true but perform another action if that condition is false.

  • This can be done with an if-else statement.

  • In R, the form of an if-else statement is the following:

if( condition ) {
    code_chunk1
} else {
    code_chunk2
}
  • As with if statements, condition is usually a logical expression, but could just be a logical vector (with a single element).

  • If condition evaluates to TRUE, code_chunk1 will be executed.

  • Otherwise, if condition evaluates to FALSE, code_chunk2 will be executed.


  • As an example, let’s write an if-else statement that computes the absolute value of a number.
x <- -3.2
if( x > 0 ) {
   abs_x <- x   # assign the variable abs_x the 
                # value stored in x
} else {
   abs_x <- -x   # assign the variable abs_x the 
                 # negative of the value stored in x
}
abs_x   # print the value stored in abs_x
## [1] 3.2
  • Another if-else example:
x <- 5
if( x%%2 == 0 ) { # arithmetic operation x%%2 evaluated first
   "Hello"
} else {
   "world"
}
## [1] "world"
  • Another if-else example:
x <- 5
if( x%%2 == 0 | x > 4) {
   "Hello"
} else {
   "world"
}
## [1] "Hello"

2.3.1 if-else-if chains

  • In many cases, a desired computation will depend on more than 2 conditions.

  • For these cases, you can use an if - else if - else chain of conditional statements.

  • The general syntax for an if - else if - else chain in R is:

if ( condition1 ) {  ## If condition1 is TRUE,
    code_chunk1     ##  code_chunk1 will be executed.
} else if ( condition2 ) { ## If condition1 is FALSE
                           ## and condiiton2 is TRUE,
    code_chunk2          ## code_chunk2 will be executed
} else if ( condition3 ) { ## If both conditions 1 and 2 are FALSE
                           ## and condition3 is TRUE,
   code_chunk3             ## code_chunk3 will be executed
}
.
.
} else {      ## If all previous conditions are FALSE,
   else_chunk  ##  else_chunk will be executed
}
  • An if-else if-else example:
x = 2
if ( x < 0 ) {        ## If the condition is TRUE,
  "x is negative"     ## this statement will run.
} else if ( x == 0 ) {## If previous conditions are FALSE but this
  "x is zero"         ## is TRUE, this statement will run.
} else {              ## If previous conditions are FALSE,
  "x is positive"     ## this statement will run.
}
## [1] "x is positive"
  • Another if-else if-else example:
message <- "second"
if ( message == "first" ) {   
    "hello"
} else if ( message == "second" ) {
    "world"
} else {
    "nothing"
}
## [1] "world"

  • Be careful about the location of else in if-else if-else statements

  • In R, you do not want to start a line with else if or else.

  • For example, the following if-else statement will not run

x <- 3
if(x < 0) {
  "x is negative"
}
else {
   "x is not negative"
}

2.3.2 Nested if-else statements

  • You can certainly have if-else statements within a conditional statement.
x = 3
if ( x %% 2 == 0 ) {  ## first condition
  if ( x < 0) {       ## second condition 
    "x is even and negative"
  } else {
    "x is even and non-negative"
  } 
}  else if ( x < 0 ) {## this if statement is not nested
  "x is odd and negative"         
} else {              ## not nested either
  "x is odd and non-negative"     
}
## [1] "x is odd and non-negative"

2.4 The ifelse function

  • The ifelse function is a useful function that acts as a “vectorized” if-else statement.

  • The general form of the ifelse function is

ifelse(test, yes, no)
- `test` is either a logical vector or a logical expression that evaluates to a logical vector
- `yes` is the value to return for each element where `test` is `TRUE`
- `no` is the value to return for each element where `test` is `FALSE`
  • Note that the ifelse function will return a vector of the same length as test

  • As an example of running the ifelse function, let’s see what it returns if we choose test as the logical vector c(TRUE, FALSE, TRUE) and yes = 5 and no = -5:
ifelse( c(TRUE, FALSE, TRUE), 5, -5)
## [1]  5 -5  5
  • The ifelse function returns the vector c(5, -5, 5).
    • The first element of test is TRUE, so the first element of the returned vector is 5.
    • The second element of test is FALSE, so the second element of the returned vector is -5.
    • The third element of test is TRUE, so the third element of the returned vector is 5.

  • It is more typical to use a logical expression as the first argument of ifelse rather than explicitly using a logical vector as the first argument.

  • For example, suppose we have defined the variable x as

x <- c(2, -2, 10)
  • Then, the following call of ifelse will return the same vector as running ifelse( c(TRUE, FALSE, TRUE), 5, -5)
ifelse(x > 0, 5, -5)
## [1]  5 -5  5
  • Inside the ifelse function call above, the logical expression x > 0 evaluates to the logical vector c(TRUE, FALSE, TRUE).

  • As another example, suppose we have data collected on two biomarkers.

  • The first biomarker is a numeric score and the second biomarker is the result of a test that is either “positive” or “negative”.

  • If the value of the first biomarker is greater than 10 and the second biomarker is “positive”, then the patient is considered to be “high risk”. Otherwise, the patient is considered to be “low risk”.

  • The ifelse function is very useful for using the information from these two biomarkers to create a “high risk” vs. “low risk” variable.

  • If the patient biomarker information is stored in the vectors biomarker1 and biomarker2, the following code uses ifelse to create a new vector risk.category which labels patients as either “high risk” or “low risk”

biomarker1 <- c(6.5, 27.3, 2.1, 5.4, 12.1, 17.3)
biomarker2 <- c("pos", "pos", "neg", "pos", "neg", "pos")

risk.category <- ifelse(biomarker1 > 10 & biomarker2=="pos", "high", "low")
risk.category
## [1] "low"  "high" "low"  "low"  "low"  "high"

2.5 Exercises

  1. What will be printed to the screen if you run the R code below?
x <- 2
if(3 < 2 | TRUE) {
    x <- 2*x
} else {
    x <- 0
}
print(x)
  1. What will be printed to the screen if you run the R code below?
x <- 2
if(3 < 2 | TRUE) {
    x <- 2*x
} else {
    x <- 0
}
print(x)
  1. What number will be printed to the screen if you run the R code below?
if(3 > 2 & 4 > 3) {
    x <- 2
} else if(3 > 2 | 3 < 4) {
    x <- 3
} else {
    x <- 4
}
  1. What will the value of the variable z be after running the following code:
z <- 1
x <- c(1, -1)
if(x[1] > 0 & (x[2] > 0 | TRUE) ) {
    z <- 5*z 
}
  1. Suppose we use the ifelse function to create the vector w using the following code:
x <- c(-1, 0, -2, 2, -3, 4)
y <- c("a", "c", "a", "b", "d", "a")
z <- c(2, 2, 2, 2, 0, 0)

w <- ifelse((x > 0 | y=="a") & z==2, 1, 0)

What is the value of w[3] and what is the value of sum(w).