Chapter 7 Loops and Conditionals
7.1 What is a loop?
- Loops are automations that take care of repetitive tasks
- Typically, we might go through data row by row and perform a task
- Loops can have different forms:
- for: loop over a pre-defined set of values, such as a number sequence
- while: define constraints and keep loop running as long as they are met
- repeat: loop repeats until broken (I do not recommend this ever!)
- For is most common, while is nice for more advanced simulations
7.1.1 What are conditionals?
- Conditionals define different actions for different conditions
- They follow intuitive language:
- if: define action to take when condition is met (logical)
- else if: define action for another condition
- else: define action for everything else
- ifelse is the shortcut-function we already got to know for recoding with
mutate()
- defines exactly 1 condition, 1 action, 1 alternative
- expandable version of ifelse is case_when
7.2 Exercise: What should I use?
- I want to print numbers from 1 to 7!
- for loop (but realistically 1:7 ;) )
- I need to simulate more data as long as my sample size is smaller than 200!
- while loop
- I want to print the age of only the females in my sample!
- if/ else
7.3 for-loop
- In a for loop, we need to define the range for which the loop should run
- We define an iterating variable that will change each time the loop runs and take on all values of the defined range
- Typically, we call this variable "i"
- We define the range in round brackets and all actions the loop should take in curly brackets
7.3.3 Conditionals: If - else
7.4 Same function, different variables
for(i in c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")){
print(mean(iris[ , i]))
}
# [1] 5.843333
# [1] 3.057333
# [1] 3.758
# [1] 1.199333
Brainteaser : What is the class() of i here?
character
7.4.1 More sophisticated
vector <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")
for(i in 1:length(vector)){
print(paste("The mean value of", vector[i], "is",
round(mean(iris[ , vector[i]]), 2)))
}
# [1] "The mean value of Sepal.Length is 5.84"
# [1] "The mean value of Sepal.Width is 3.06"
# [1] "The mean value of Petal.Length is 3.76"
# [1] "The mean value of Petal.Width is 1.2"
Brainteaser : And what is the class() of i now?
integer (numeric)
7.4.2 With saving values
vector <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")
means <- rep(NA, length(vector)) # create "empty" vector to fill
for(i in 1:length(vector)){
print(paste("The mean value of", vector[i], "is",
round(mean(iris[ , vector[i]]), 2)))
means[i] <- round(mean(iris[ , vector[i]]), 2)
}
# [1] "The mean value of Sepal.Length is 5.84"
# [1] "The mean value of Sepal.Width is 3.06"
# [1] "The mean value of Petal.Length is 3.76"
# [1] "The mean value of Petal.Width is 1.2"
7.4.3 Exercise: Seminar Data
Please download an edited version of our seminar data from ILIAS. You will find it under data as a zip folder. The dataset in it should have ".Rds" as a file ending. Read it in using:
Create a for-loop that saves the means of age, body height and technological skill from that seminar data in a vector named "seminar_means".
Hint: I renamed the variables to make them nicer to work with, so check out names(seminar)!
7.4.5 Checking What's Going On
7.4.5.1 browser()
- In order to break our loop and enter a "debugging" mode, we can add browser() to any loop like so:
vector <- c("v02_age", "v04_bodyheight", "v05_skill_tech")
seminar_means <- rep(NA, length(vector)) # create "empty" vector to fill
for(i in 1:length(vector)){
seminar_means[i] <- round(mean(seminar[ , vector[i]]), 2)
browser()
}
The loop will run the first iteration until browser is called and then pause
It allows you to check in the console whether all variables look the way you want them to without having to wait for the loop to run
- Or if there are errors/ warnings, you can check when they occur by moving the browser() to a different location in the code
To continue with the next iteration while in browser, type "c" into the console, "Q" to quit
- The Esc key will also terminate the browser
Make sure you exit it before continuing with anything else
7.5 Loop with Conditional
In our seminar data, the average body height is 167.23 cm. We want to create a loop that goes through all rows (all seminar students) and outputs their height and whether it is above or below average.
What do we need for that?
7.5.1 Elements
- For each person:
- Check if their body height is above average
- If yes: Output "This person is taller than average with ..."
- Else: Output "This person is less tall than average with..."
- Then paste the person's body height
- Loop that over each person!
for(i in 1:nrow(seminar)){
if(seminar$v04_bodyheight[i] > mean(seminar$v04_bodyheight)) {
print(paste("This person is taller than average with", seminar$v04_bodyheight[i], "cm."))
} else {
print(paste("This person is less tall than average with", seminar$v04_bodyheight[i], "cm."))
}
}
# [1] "This person is taller than average with 168 cm."
# [1] "This person is less tall than average with 160 cm."
# [1] "This person is taller than average with 171 cm."
# [1] "This person is less tall than average with 166 cm."
# [1] "This person is taller than average with 169 cm."
# [1] "This person is less tall than average with 164 cm."
# [1] "This person is less tall than average with 161 cm."
# [1] "This person is less tall than average with 166 cm."
# [1] "This person is taller than average with 183 cm."
# [1] "This person is taller than average with 172 cm."
# [1] "This person is less tall than average with 160 cm."
# [1] "This person is less tall than average with 164 cm."
# [1] "This person is taller than average with 170 cm."
7.5.2 And a more complicated outlook...
7.5.2.1 What happens here?
for(i in 1:nrow(seminar)){
if(seminar$v11_soul[i] == "yes"){ # Check soul belief
text1 <- "This person belives in the soul and"
} else if (seminar$v11_soul[i] == "no") {
text1 <- "This person does not belive in the soul and"
} else { text1 <- "This person is unsure about the soul and" }
if(seminar$v12_soul_phil[i] == "monism"){ # Check mind-body-philosophy
text2 <- "believes the m-b-relationship is monistic."
} else if (seminar$v12_soul_phil[i] == "dualism") {
text2 <- "believes the m-b-relationship is dualistic."
} else { text2 <- "is unsure of the m-b-relationship." }
print(paste(text1, text2)) # Print text
}
7.5.3 Result
# [1] "This person belives in the soul and believes the m-b-relationship is dualistic."
# [1] "This person belives in the soul and is unsure of the m-b-relationship."
# [1] "This person belives in the soul and believes the m-b-relationship is monistic."
# [1] "This person is unsure about the soul and is unsure of the m-b-relationship."
# [1] "This person belives in the soul and is unsure of the m-b-relationship."
# [1] "This person does not belive in the soul and believes the m-b-relationship is monistic."
# [1] "This person is unsure about the soul and is unsure of the m-b-relationship."
# [1] "This person is unsure about the soul and is unsure of the m-b-relationship."
# [1] "This person does not belive in the soul and is unsure of the m-b-relationship."
# [1] "This person belives in the soul and believes the m-b-relationship is monistic."
# [1] "This person is unsure about the soul and believes the m-b-relationship is dualistic."
# [1] "This person belives in the soul and believes the m-b-relationship is dualistic."
# [1] "This person is unsure about the soul and is unsure of the m-b-relationship."
Wrap-Up & Further Resources
- For-Loops must have a defined sequence to run over, e.g. 1 to 4
- For-loops are the most common in R and are fit for most tasks
- Loops are a powerful tool to e.g. easily perform the same task many times
- Conditionals give you control over different operations depending on your data
- In combination, loops and conditionals are most useful
- Don't forget to play and create fun loops!
- For loops (W3 Schools)
- For loops (R bloggers)
- For loops (DataMentor) Here are also links the the other types of loop and a visualization
- Loops in R (datacamp) Very thorough! :)
- dplyr Exercises Great to keep practicing over the holidays :)
