In this article we are going to learn:
Flow control-if
Loops-for, while, repeat
Advanced loop-*ply
At the beginning of each for-loop is a head that defines a collection of objects such as the elements of a vector or a list.
The head is followed by a code block (i.e. the body of our loop). In this block we can execute basically any R syntax we want.
Afterwards, the for-loop checks whether it reached the last object of the collection specified in the head of the loop. If this is the case, the for-loop is stopped. If this is not the case, the code block within the for-loop is repeated.
So keep on reading!
#Example 1: Use for-loops to loop over a vector.
for(i in 1:6) { # Head of for-loop
x1 <- i^2 # Code block
print(x1) # Print results
}
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25
## [1] 36
#Example 2: Loop over character vectors
mba<- c("Nargiz", "Altunay", "Cavadkhan", "Maga", "Nabi") # Create character vector
for (name in mba) {
print(paste("The name", name, "consists of", nchar(name), "characters."))
}
## [1] "The name Nargiz consists of 6 characters."
## [1] "The name Altunay consists of 7 characters."
## [1] "The name Cavadkhan consists of 9 characters."
## [1] "The name Maga consists of 4 characters."
## [1] "The name Nabi consists of 4 characters."
#Example 3: shows how to concatenate the output of each for-loop iteration to a vector. For this task, we first have to create an empty vector:
vec <- numeric() # Create empty data object
#Now, we can use the for-statement to create a vector of output values:
for(i in 1:10) { # Head of for-loop
vec <- c(vec, i^2) # Code block
}
#Let’s print the results:
vec
## [1] 1 4 9 16 25 36 49 64 81 100
#Example 4: Nested for-Loop in R.
#Let’s first create another empty vector (as in Example 3):
vec <- character() # Create empty data object
#Now, we can use the following nested for-loop to create a vector were each vector element contains two (different) letters of the alphabet:
for(i in 1:5) { # Head of first for-loop
for(j in 1:3) { # Head of nested for-loop
vec<- c(vec, paste(LETTERS[i], letters[j], sep = "_")) # Code block
}
}
vec #print the result
## [1] "A_a" "A_b" "A_c" "B_a" "B_b" "B_c" "C_a" "C_b" "C_c" "D_a" "D_b" "D_c"
## [13] "E_a" "E_b" "E_c"
#Example 5: Break for-Loop Based on Logical Condition It is possible to specify a logical if-condition within a for-loop that stops the execution of the loop in case it is TRUE. This Example explains how to stop a loop when the if-condition i >=5 is fulfilled. For this, we have to use the break-statement within the if-condition:
for(i in 1:10) { # Head of for-loop
print(i^2) # Print results
if(i >= 5) { # Conditionally stop for-loop
break # Using break-statement
}
}
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25
#Example 6: Continue to Next Iteration of for-Loop
#Similar to Example 5, we can also skip a for-loop iteration using the next-statement. The following for-loop is skipped at the index positions 1, 5, and 7:
for(i in 1:10) { # Head of for-loop
if(i %in% c(1, 5, 7)) { # Conditionally skip iteration
next # Using next-statement
}
print(i^2) # Print results
}
## [1] 4
## [1] 9
## [1] 16
## [1] 36
## [1] 64
## [1] 81
## [1] 100
#Example 7: for-Loop Over Data Frame Columns
data(iris) # Loading iris flower data set
head(iris) # Inspecting iris flower data set
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
#Our example data frame contains five columns consisting of information on iris flowers. Let’s also replicate our data in a new data frame object called iris_new1:
iris_new <- iris # Replicate iris data set
#Now, we can loop over the columns of our data frame using the ncol function within the head of the for-statement. Within the for-loop, we are also using a logical if-condition:
for(i in 1:ncol(iris_new)) { # Head of for-loop
if(grepl("Width", colnames(iris_new)[i])) { # Logical condition
iris_new[ , i] <- iris_new[ , i] + 1000 # Code block
}
}
#Let’s have a look at the updated data frame:
head(iris_new)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 1003.5 1.4 1000.2 setosa
## 2 4.9 1003.0 1.4 1000.2 setosa
## 3 4.7 1003.2 1.3 1000.2 setosa
## 4 4.6 1003.1 1.5 1000.2 setosa
## 5 5.0 1003.6 1.4 1000.2 setosa
## 6 5.4 1003.9 1.7 1000.4 setosa
#As you can see, we have added +1000 to each column that contained the character pattern “Width”.
#Two more examples
if(runif(1) > 0.5) message("This message appears with a 50% chance.")
## This message appears with a 50% chance.
for(month in month.name)
{
message("The month of ", month)
}
## The month of January
## The month of February
## The month of March
## The month of April
## The month of May
## The month of June
## The month of July
## The month of August
## The month of September
## The month of October
## The month of November
## The month of December
for-loops can be very handy when you want to draw multiple plots efficiently within a few lines of code. Let’s assume that we want to draw a plot of each numeric column of the iris data frame. Then, we can use the following R code:
for(i in 1:(ncol(iris) - 1)) { # Head of for-loop
plot(1:nrow(iris), iris[ , i]) # Code block
Sys.sleep(1) # Pause code execution
}
i<-1
while (i<=6)
{
print(i)
i=i+1
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
Example: Running while-Loop Through Data Frame Columns
data(iris)
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
As you can see, the iris flower data frame contains five columns. The first four columns are numeric and the last column has the factor class. Let’s assume that we want to iterate through these variables until we reach the first non-numeric variable. Until then, we want to add +50 to the values of the variable used in the current iteration.
In this case, we first have to specify a running index that is increase with each iteration. We are starting with the first column:
running_index <- 1 # Create index
#Then, we can start running our while-loop as shown below:
while(is.numeric(iris[ , running_index])) {
iris[ , running_index] <- iris[ , running_index] + 50
running_index <- running_index + 1
}
#Let’s have a look at our updated data frame:
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 55.1 53.5 51.4 50.2 setosa
## 2 54.9 53.0 51.4 50.2 setosa
## 3 54.7 53.2 51.3 50.2 setosa
## 4 54.6 53.1 51.5 50.2 setosa
## 5 55.0 53.6 51.4 50.2 setosa
## 6 55.4 53.9 51.7 50.4 setosa
Each numeric variable was increased by 50.
Obviously you may make the content blocks within the while-loops more complex (e.g. detailed break and exit conditions or using functions with multiple conditions) to generate more advanced outputs.
Classwork:
Also, lets talk about switch() function.
# Following is a simple R program to demonstrate syntax of switch.
val <- switch(4,"Case1","Case2","Case3","Case4","Case5","Case6")
print(val)
## [1] "Case4"
#Second switch() example: Mathematical calculation
val1 = 6
val2 = 7
val3 = "s"
result = switch(
val3,
"a"= cat("Addition =", val1 + val2),
"d"= cat("Subtraction =", val1 - val2),
"r"= cat("Division = ", val1 / val2),
"s"= cat("Multiplication =", val1 * val2),
"m"= cat("Modulus =", val1 %% val2),
"p"= cat("Power =", val1 ^ val2)
)
## Multiplication = 42
print(result)
## NULL