11 Search and Conditions
Objective: To learn about control flow (decision making) structures in R, mainly if/else
We will cover:
- grep and grepl
- conditional operator (review)
- if{}else{}
- ifelse()
Recall: logical is a basic data type in R. The values are either TRUE or FALSE. (short-form T or F)
# Examples
<- T# logical value
x is.logical(x) # returns a logical
## [1] TRUE
<- c(T, F, T) #logical vector x
11.1 General Expressions
regular expressions can be used to see whether a pattern exists inside a character string or a vector of character strings
functions: grepl() = returns a logical vector; TRUE when a pattern is found in the corresponding character string grep() = returns a numeric vector of indices of the character strings that contains the pattern
Arguments: - pattern = regular expression you want to match for - x = character vector from which matches should be sought
Read more: https://bookdown.org/rdpeng/rprogdatascience/regular-expressions.html
# Define a character vector with emails
<- c("ka@gmail.com", "edu@who.int", "me@gmail.com", "invalid.edu", "jane@utoronto.ca", "jane@gmail.com")
emails # Search for emails with "gmail.com
# use grep
grep(pattern = "gmail.com", x = emails)
## [1] 1 3 6
# use grepl
<- grepl(pattern = "gmail.com", x = emails)
is.gmail is.gmail
## [1] TRUE FALSE TRUE FALSE FALSE TRUE
# now you can index the emails vector
emails[is.gmail]
## [1] "ka@gmail.com" "me@gmail.com" "jane@gmail.com"
11.2 Conditions
- Decision making is important in programming.
- Conditions are statements that are created by the programmer which evaluates actions in the code to check if it’s true or false.
if/else statements
This is achieved using the conditional if..else statement
if (test_expression) { statement }
The condition, test_expression must return TRUE or FALSE. If it returns TRUE, the block of code (ie. statement) inside the curly brackets will be run.
# Example 1
<- -3
x # Read the following as: if x is less than 0, print "x is a negative number"
if(x < 0){
print("X is a negative number.")
}
## [1] "X is a negative number."
# Example 2
<- 1:400
values <- T
do_log # If do_log is TRUE, we log the values in the brackets
if(do_log){
print("do_log is TRUE")
<- log(values)
values }
## [1] "do_log is TRUE"
You may pair the if{} statement with an else (optional). If the test expression for if is FALSE, the code within else{} will run.
if (test_expression) {
statement1
} else {
statement2
}
<- -3
x # Read the following as: if x is less than 0, print "x is a negative number"
if(x < 0){
print("X is a negative number.")
else{
}print("X is a positive number.")
}
## [1] "X is a negative number."
Note: you can also have an ifelse ladder - It allows you execute a block of code among more than 2 alternatives.
if ( test_expression1) {
statement1
} else if ( test_expression2) {
statement2
} else if ( test_expression3) {
statement3
} else {
statement4
}
<- 4
x # Read the following as: if x is less than 0, print "x is a negative number"
if(x < 0){
print("X is a negative number.")
else if (x > 0) {
} print("X is a positive number.")
else {
} print("X is 0.")
}
## [1] "X is a positive number."
11.3 any() and all()
Check whether any or all of the elements of a vector are TRUE.
# continuing emails example...
# Check if any emails are gmail
if(any(grepl("gmail.com", emails))){
print("There are gmail accounts in the emails vector.")
else{
}print("There are no gmail accounts.")
}
## [1] "There are gmail accounts in the emails vector."
# check if all of the emails are gmail
if(all(grepl("gmail.com", emails))){
print("All emails are gmail accounts.")
else{
}print("Not all emails are gmail accounts.")
}
## [1] "Not all emails are gmail accounts."
11.4 Operators
Make test expressions using logical and boolean operators Recall from tutorial 1..
Logical operators
return TRUE or FALSE, important for later on when we learn about control structures
Relational operators used to compare between values
< for less than
\> for greater than
<= for less than or equal to
\>= for greater than or equal to
== for equal to each other
!= not equal to each other
Boolean operators used as conjunctions for logical operations
- ! Logical NOT # convert
- & Element-wise logical AND # will be false if at least one element is false
- Element-wise logical OR # will be true if at least one element is true
# Assign logical values to variables
<- TRUE
im_tall <- FALSE
im_short <- TRUE
im_nice # NOT
!im_tall # I'm NOT tall = FALSE
## [1] FALSE
# AND
& im_short im_nice
## [1] FALSE
& im_tall im_nice
## [1] TRUE
# OR
| im_short im_nice
## [1] TRUE
# combine using parentheses (not square brackets or braces)
# like BEDMAS - perform what's in () brackets first
| im_short) & im_tall (im_nice
## [1] TRUE
Combine Boolean operators with functions that return logical values.
# check if any of the emails are not gmail using NOT !
if(any(! grepl("gmail.com", emails))){
print("Some or all emails are not gmail accounts.")
}
## [1] "Some or all emails are not gmail accounts."
11.5 ifelse()
Say you have an if/else statement where you’re assigning a value to a variable based on a condition.
Example
<- 20
x if(x < 0){
<- "negative"
result else{
}<- "positive"
result }
You can use the ifelse() function in R to shorten this code. ifelse(test_expression, x, y) where if test_expression is T, x is returned if T, else y is returned Read more: https://www.datamentor.io/r-programming/ifelse-function/
<- ifelse(x < 0, "negative", "positive")
result
# If x is between 10 and 30, return x, or else add 30 to x
<- ifelse(x < 30 & x > 10, x, x+30) result
11.6 Practice
- Define a numeric variable, x, that belongs to any number you like.
- If x is less than 10, print “x is less than 10” to the console.
- Add an else part to your if statement. print “x is not less than 10” to the console.
- Define a vector of 5 numeric values, called v.
- Print the values in v that are greater than x to console.
Solution
# a)
<- 5
x # b)
if(x < 10){
print("x is less than 10")
}
## [1] "x is less than 10"
# c)
if(x < 10){
print("x is less than 10")
else{
}print("x is not less than 10")
}
## [1] "x is less than 10"
# d)
<- 3:7 # or v <- c(3,52,7,2,31)
v # e)
>x] v[v
## [1] 6 7