R Exercises – 71-80 – Loops (For Loop, Which Loop, Repeat Loop), If and Ifelse Statements in R
1. Simple ifelse statement
Create the data frame ‘student.df’ with the data provided below:
student.df = data.frame( name = c("Sue", "Eva", "Henry", "Jan"), sex = c("f", "f", "m", "m"), years = c(21,31,29,19)); student.df
Use a simple ‘ifelse’ statement to add a new column ‘male.teen’ to the data frame. This is a boolean column, indicating T if the observation is a male younger than 20 years.
#expected result name sex years male.teen 1 Sue f 21 F 2 Eva f 31 F 3 Henry m 29 F 4 Jan m 19 T
student.df = data.frame( name = c("Sue", "Eva",
"Henry", "Jan"),
sex = c("f", "f", "m", "m"),
years = c(21,31,29,19));
student.df
student.df$male.teen = ifelse(student.df$sex == "m" &
student.df$years < 20, "T", "F")
student.df
2. Double for loop
Write a double for loop which prints 30 numbers (1:10, 2:11, 3:12). Those are three clusters of ten numbers each. The first loop determines the number of clusters (3) via its length; the second loop the numbers to be printed (1 to 10 at the beginning). Each cluster starts one number higher than the previous one.
#expected result [1] 1 [1] 2 [1] 3 [1] 4 [1] 5 [1] 6 [1] 7 [1] 8 [1] 9 [1] 10 [1] 2 [1] 3 [1] 4 [1] 5 [1] 6 [1] 7 [1] 8 [1] 9 [1] 10 [1] 11 [1] 3 [1] 4 [1] 5 [1] 6 [1] 7 [1] 8 [1] 9 [1] 10 [1] 11 [1] 12
for (i in 1:length(1:3)) {
for (j in 1:10) {
print(j+i-1)
}}
3. Simple repeat loop
Write a repeat loop containing three random numbers. The loop repeats itself exactly ten times before it stops.
#expected result [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671 [1] 0.1932123 -0.4346821 0.9132671
set.seed(23)
randomnr <- rnorm(3)
reps <- 1
repeat {
print(randomnr)
reps <- reps + 1
if(reps > 10) {
break}}
4. For loop combined with if statement
Write a for loop that prints the Displacement (‘disp’) of the ‘mtcars’ dataset.
a. This loop will only print observations of 160 or higher in ‘disp’.
b. This loop will stop as soon as an observation is smaller than 160 in ‘disp’.
#expected result #a [1] 160 [1] 160 [1] 258 [1] 360 [1] 225 [1] 360 [1] 167.6 [1] 167.6 [...] #b [1] 160 [1] 160
for (i in mtcars$disp){
if(i<160)
next
print (i)}
for (i in mtcars$disp){
if(i<160)
break
print (i)}
5. Adding a new column to a data.frame – NA handling
a. You have the data.frame ‘mydf’ with four columns like below.
a = c(3,7,NA, 9) b = c(2,NA,9,3) f = c(5,2,5,6) d = c(NA,3,4,NA) mydf = data.frame(a=a,b=b,f=f,d=d);mydf
b. You want to add another column ‘5’:
- the 5th column contains the value of col 2 if col 1 is NA;
- the 5th column contains the value of col 4 if col 2 is NA;
- the 5th column contains the value of col 3 in all other cases.
#expected result a b f d V5 1 3 2 5 NA 5 2 7 NA 2 3 3 3 NA 9 5 4 9 4 9 3 6 NA 6
a = c(3,7,NA, 9)
b = c(2,NA,9,3)
f = c(5,2,5,6)
d = c(NA,3,4,NA)
mydf = data.frame(a=a,b=b,f=f,d=d);mydf
mydf[,5] <- ifelse(is.na(mydf[,1]) & !is.na(mydf[,2]),
mydf[,2],
ifelse(is.na(mydf[,2]) & !is.na(mydf[,4]),
mydf[,4], mydf[,3]))
mydf
6. Simple while loop
Write a while loop starting with x = 0. The loop prints all numbers up to 35 but it skips number 7.
#expected result [1] 1 [1] 2 [1] 3 [1] 4 [1] 5 [1] 6 [1] 8 [1] 9 [1] 10 [1] 11 [...]
x = 0
while(x < 35) {
x = x+1
if (x == 7) next
print(x)}
7. While loop – multi matches
We are using the same while loop as in the last exercise. The loop prints again all numbers up to 35, but this time it skips a whole vector of numbers: 3,9,13,19,23,29.
#expected result [1] 1 [1] 2 [1] 4 [1] 5 [1] 6 [1] 7 [1] 8 [1] 10 [1] 11 [1] 12 [1] 14 [1] 15 [1] 16 [1] 17 [1] 18 [1] 20 [1] 21 [1] 22 [1] 24 [1] 25 [1] 26 [1] 27 [1] 28 [1] 30 [1] 31 [1] 32 [1] 33 [1] 34 [1] 35
exclude = c(3,9,13,19,23,29)
x = 0
while(x < 35) {
x = x+1
if (x %in% exclude) next
print(x)}
8. Urn experiment – advanced exercise
You have an urn with balls from 1 to 100. You want to find out how often you need to draw a ball to get number 55. This is an experiment with replacement – you put the ball back each time you draw. Simulate 1000 runs of the experiment to get an accurate estimation of the required draws.
Use seed 23 to make the experiment reproducible. Use loops (for, while) for the solution.
set.seed(23) #expected result [1] 97.256
set.seed(23)
repetitions <- 1000
urn <- c(1:100) # container of 100 numbers
trialsto100 <- 0 # trials to get the desired number
for (i in 1:repetitions){
num <- 0 # the sampled number
trials <- 0
while(num != 55){ # we want number 55
num <-sample(urn, 1, F) # sampling of the urn
trials <- trials + 1 # looping the trials until we get the desired output
}
trialsto100 <- trialsto100 + trials # updating the number of trials
}
trialsto100/repetitions
9. Simulating a pair of dice – hard
Get 1000 simulations of a paired dice game.
- A game immediately stops if you have an initial total (2 dice) of 5,6,7,8,9.
- If the first cast does not meet those 5 totals you would continue until you get either 11 or 12.
- What is the average number of dice casts per game?
set.seed(23) #expected result [1] 5.011
set.seed(23)
n.sim = 1000 # number of simulations
cts = rep(0, n.sim) # counts of dice casts
x = NULL # container for the current cast total
for (i in 1:n.sim) {
start = c(sample(1:6,1) + sample(1:6,1)) # a pair of dice
cts[i] = cts[i] + 1 # update of cast counts
x = start
if(x %in% c(5,6,7,8,9)){ # initial target totals
next} # stop the game if this total is casted
repeat {
x = c(sample(1:6,1) + sample(1:6,1))
cts[i] = cts[i] + 1
if(x %in% c(11, 12)){ # new target of the repeat loop
break
}}}
mean(cts)
10. River classifications
Use the ‘rivers’ dataset to write a for loop. The loop prints the dataset:
- rivers shorter than 500 are a ‘short river’;
- rivers longer than 2000 are a ‘long river’;
- and rivers in the middle range are printed in their original numbers.
#expected result [1] 735 [1] "short river" [1] "short river" [1] "short river" [1] 524 [1] "short river" [1] 1459 [1] "short river" [1] "short river" [1] 600 [1] "short river" [...]
for (i in rivers){
if(i<500){
print("short river")
} else if (i>2000) {
print("long river")
} else{
print(i)}
}