Our previous lessons have shown us how to manipulate data, and repeat things. However, the programs we have written so far always do the same things, regardless of what data they’re given.We want programs to make choices based on the values they are manipulating.
There are many instances where we need our code to do different things in different scenarioes. In other words, we need to write code that given some information automatically decides between multiple options. The tool R gives us for doing this is called a conditional statement, and looks like this:
num <- 37
if (num > 100) {
print("greater")
} else {
print("not greater")
}
print("done")
## [1] "not greater"
## [1] "done"
The second line of this code uses an if
statement to tell R that we want to make a choice. If the following test is true, the body of the if
(i.e., the lines in the curly braces underneath it) are executed. If the test is false, the body of the else
is executed instead. Only one or the other is ever executed:
In the example above, the test num > 100
returns the value FALSE
, which is why the code inside the if
block was skipped and the code inside the else
statement was run instead.
num > 100
## [1] FALSE
And as you likely guessed, the opposite of FALSE
is TRUE
.
num < 100
## [1] TRUE
Conditional statements don’t have to include an else
. If there isn’t one, R simply does nothing if the test is false:
num <- 53
if (num > 100) {
print("num is greater than 100")
}
We can also chain several tests together when there are more than two options. For example if we wanted to write some code that returned the sign of a number:
num<- -3
if (num > 0) {
print(1)
} else if (num == 0) {
print(0)
} else {
print(-1)
}
## [1] -1
Note that when combining else
and if
in an else if
statement (similar to elif
in Python), the if
portion still requires a direct input condition. This is never the case for the else
statement alone, which is only executed if all other conditions go unsatisfied. Note that the test for equality uses two equal signs, ==
.
Other Comparisons
Other tests include greater than or equal to (
>=
), less than or equal to (<=
), and not equal to (!=
).
We can also combine tests. An ampersand, &
, symbolizes “and”. A vertical bar, |
, symbolizes “or”. &
is only true if both parts are true:
if (1 > 0 & -1 > 0) {
print("both parts are true")
} else {
print("at least one part is not true")
}
## [1] "at least one part is not true"
while |
is true if either part is true:
if (1 > 0 | -1 > 0) {
print("at least one part is true")
} else {
print("neither part is true")
}
## [1] "at least one part is true"
In this case, “either” means “either or both”, not “either one or the other but not both”.
We can also write a conditional to check if a character string in contained in a particular set. To this we use %in%
which checks if the variable on the left is contained within the variable on the right.
pets<-c("cat", "dog", "horse") ## a vector of character strings
"cat" %in% pets
## [1] TRUE
"monkey" %in% pets
## [1] FALSE
As the outputs are TRUE or FALSE we can use this in an if else statement.
gw4<-c("Bath", "Bristol", "Cardiff", "Exeter")
location<-"Exeter"
if(location %in% gw4){
print("Part of GW4")
} else {
print("Outsider!")
}
## [1] "Part of GW4"
location<-"Newcastle"
if(location %in% gw4){
print("Part of GW4")
} else {
print("Outsider!")
}
## [1] "Outsider!"
If else statements can be used when you want to evaluate a conditional one by one. In other words it can only process one TRUE/FALSE statement at a time. Conditionals can also be used to subset vectors, matrices or data.frames.
numbers<-c(4,1,9,7,2,3)
numbers[numbers > 5]
## [1] 9 7
numbers[numbers < 0]
## numeric(0)
The %in%
operator an also be used in a similar way.
pets<-c("cat", "dog", "horse")
animals<-c("monkey", "cat", "dog", "cow", "cat")
animals[animals %in% pets]
## [1] "cat" "dog" "cat"
The presence of an !
at the beginning of the conditional inverts the meaning of the conditional statement. E.g to return all elements of animals
that are not found in pets
:
animals[!animals %in% pets]
## [1] "monkey" "cow"
There may be occasions where you need to know which elements satisfy a criteria, in this case which()
can be used to identify which elements meet a conditional and returns a list of indexes that meet that condition.
numbers<-c(4,1,9,7,2,3)
which(numbers > 5)
## [1] 3 4
which(numbers < 0)
## integer(0)
If we want to count the number of elements that satisfy a criteria we can use sum()
, as TRUE takes the value 1 and FALSE 0, summing across a logical vector of TRUE and FALSE effectively counts the number of TRUE. We can use !
in our criteria to instead count the number of FALSE (as they are converted to TRUE).
## count how many entries in numbers are greater than 5
sum(numbers > 5)
## [1] 2
## count how many entries in animals are not in pets
sum(!animals %in% pets)
## [1] 2