Week 3 Tutorial: Control Flow in R

POP77001 Computer Programming for Social Scientists

Note on Code Formatting

  • Use consistent style and indentation (RStudio indents by 2 whitespaces, Jupyter Notebook by 4)
  • Even though it does not affect how programs are executed in R
# Good style
is_positive <- function(num) {
  if (num > 0) {
    res <- TRUE
  } else {
    res <- FALSE
  }
  return(res)
}
# Bad style
is_positive <- function(num) {
if (num > 0) {
res <- TRUE
}
else {
res <- FALSE
}
return(res)
}

Exercise 1: Conditional Statements

  • Below you will find a code snippet for finding the maximum value in vector v using exhaustive enumeration.
  • Modify it in such a way that it finds the minimum (rather than maximum) value.
  • Check that your code works correctly by applying the built-in function min().
set.seed(2026)
v <- sample(1:100, 20)
v
 [1] 93 97 38 45 91 36 48  5 31 44 58 88 19 79 10 54 18 34 12 56
max_val <- v[1]
for (i in v[2:length(v)]) {
  if (i > max_val) {
    max_val <- i
  }
}
max_val
[1] 97

  • Now let’s make this code more robust.
  • Re-write the code above so that it can handle vectors that contain NAs in them.
  • Test your code on the vector below.
set.seed(2026)
v <- sample(c(1:75, rep(NA, 25)), 20)
v
 [1] NA NA 38 45 NA 36 48  5 31 44 58 NA 19 NA 10 54 18 34 12 56

Exercise 2: Iteration

  • Recall that repeat > while > for is the order of flexibility among different iteration constructs in R.
  • The below implementation of the moving average is done using repeat loop.
  • First, study the code and make sure you understand how it works.
  • Second, re-write the code using while loop.
  • Thirds, re-write the code using for loop.
  • Modify the code to calculate a 5-point moving average instead of 3-point moving average.

set.seed(2026)
v <- sample(1:100, 20)
v
 [1] 93 97 38 45 91 36 48  5 31 44 58 88 19 79 10 54 18 34 12 56
# Preallocate a vector to hold the moving averages.
# As we are taking a 3-point moving average, the resulting vector
# will be of length 2 less than the original vector.
mas <- vector("double", length = length(v) - 2)

i <- 1

repeat {
  mas[i] <- mean(v[i:(i + 2)])

  i <- i + 1
  
  if (i > length(v) - 2) {
    break
  }
}
mas
 [1] 76.00000 60.00000 58.00000 57.33333 58.33333 29.66667 28.00000 26.66667
 [9] 44.33333 63.33333 55.00000 62.00000 36.00000 47.66667 27.33333 35.33333
[17] 21.33333 34.00000

Exercise 3: More Iteration

  • Below you see a matrix of random 30 observations of 5 variables
  • Inspect visually the matrix
  • Which variable(s) do you think has(ve) the highest standard deviation?
  • First, try subsetting individual rows and columns from this matrix
  • Check the dimensionality of the matrix using dim(), nrow() and ncol() functions
  • Write a loop that goes over each variable and calculates its standard deviation
  • You can use sd() function to calculate the standard deviation
  • Save these calculated standard deviations in a vector
  • Find the variable with the maximum standard deviation using max() or which.max() functions
  • Is it the one you thought it would be?

# When dealing with random number generation it's always a good idea to make your code replicable
# by setting the seed with set.seed(function)
set.seed(2026)
# Here we create a matrix of 30 observations of 5 variables
# where each variable is a random draw from a normal distribution with mean 0
# and standard deviation drawn from a uniform distribution between 0 and 10
mat <- mapply(
  function(x) cbind(rnorm(n = 30, mean = 0, sd = x)),
  runif(n = 5, min = 0, max = 10)
)
mat
             [,1]       [,2]        [,3]        [,4]         [,5]
 [1,] -13.6781050 -7.7087194 -2.16914035 -1.81900372   0.29705818
 [2,]   7.5797083 -0.4875531 -0.13225895 -3.04744941  -2.64631288
 [3,]   1.4249915  2.3294226 -0.31626606 -0.64116119  -7.95778099
 [4,]   3.5013766 -1.7156379  0.51118260 -3.66250553  -1.87064692
 [5,]   7.1974521  5.9590225 -1.85298111  3.90809359   2.95890958
 [6,]  -2.5641353  1.8866826 -3.69369438 -1.46252633  -5.30336834
 [7,] -21.2136266  0.5842800  0.02894001  0.37079180   7.31194516
 [8,] -14.7647722  7.1318762 -0.59166399 -2.47329693   2.08518805
 [9,]  -2.8163249  9.2386375 -0.79718249  0.95130900   1.26062841
[10,] -10.7832140  9.8841454  0.50805009  5.11239464  -3.64613906
[11,]  -6.2500272 11.1619441 -2.02015661  1.91039337  -4.57216125
[12,]  -7.5453671  8.1080630  0.49419165  5.34564427   1.32234916
[13,]   1.8015323 -4.3820201 -2.22674018  0.53783592   3.72376272
[14,]  -6.5199009  3.2787311 -2.32555196 -2.99188227  -0.31726434
[15,] -14.9551028 -3.1568328  0.12475723 -4.13497598  -4.14925033
[16,]  -1.3067312 -2.2743354  0.89705818  0.39980821   1.25072059
[17,]  -0.3995154 -1.9281338  0.72336312 -3.06521006   3.01125176
[18,]  -0.9339608 -1.8054710 -2.70262086 -1.12443647 -10.63364232
[19,]   8.0296694  5.3288677  0.01894250  0.93949092   3.95534915
[20,]  -1.0523591 -7.7443276 -1.69806156  1.86691821   2.14933375
[21,] -12.6939159 -5.0739350 -0.43339453  3.19182290   0.47367080
[22,]  -3.7734895  1.5109619 -0.18183491 -3.19960980  -8.15690788
[23,]  -5.0160724  1.2715538 -1.80765643 -2.57140115   4.04715548
[24,]   2.3650972  6.1756398  0.84511903 -2.37023116   6.62544045
[25,]   8.4355312 -2.5735107  1.10121132 -0.02472118   6.25838999
[26,]   3.9876828 -9.0699113  0.25032469  1.68025647   2.07329102
[27,] -11.7797487 -5.9644921  2.18025244 -4.18028908   0.09416032
[28,]  -5.8518655  4.2751399  0.08748227  3.54159839  -0.92129593
[29,]   8.7803765 -6.2288175 -0.85534101  0.29129352   0.06839505
[30,]  -0.7808176  4.1833822  0.46398201  2.60883474  -2.24601979