R offers different control flow structures, which allow us to control the flow of execution of a script:

`if`

,`if else`

and`else`

`switch`

`for`

`while`

`repeat`

`break`

`next`

`return`

```
if (condition) {
# do something
} else {
# do something else
}
```

A simple example cloud look like this:

```
my_age <- 14
if (my_age < 18) {
print("You are a teenager")
} else {
print("You are an adult")
}
```

`## [1] "You are a teenager"`

```
my_age <- 21
if (my_age < 18) {
print("You are a teenager")
} else {
print("You are an adult")
}
```

`## [1] "You are an adult"`

For such simple `if`

-`else`

condition there
exists a vectorized, and hence more efficient, version.

```
my_age <- 15
ifelse(my_age <= 18, "You are a teenager", "You are an adult")
```

`## [1] "You are a teenager"`

```
my_age <- 45
ifelse(my_age <= 18, "You are a teenager", "You are an adult")
```

`## [1] "You are an adult"`

Another related control flow element is the `switch()`

command, which selects one of a list of alternatives. Let us create a
function called `centre`

, which computes either the mean or
the median of a given vector.

```
centre <- function(x, type) {
switch(type,
mean = mean(x),
median = median(x)
)
}
```

Let us construct a vector \(\mathbf v\).

`v <- c(1, 2, 3, 4, 5, 1000)`

Now we call the `centre()`

function, first computing the
mean and thereafter the median of the vector \(\mathbf v\).

`centre(v, "mean")`

`## [1] 169.1667`

`centre(v, "median")`

`## [1] 3.5`

Loops are very powerful techniques for repeating some task.

**For-loops**

A `for`

loop works on an iterable variable of finite
length. `For`

loops are applied if we know in advance how
often a task shall be repeated.

Let us use a `for`

loop to print each number between 1 and
10.

```
for (i in 1:10) {
print(i)
}
```

```
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
```

We may as well loop through any iterable object, such as a vector of strings. Let us create a vector of strings.

`beatles <- c("John", "George", "Paul", "Ringo")`

We may either access the items directly…

```
for (i in beatles) {
print(i)
}
```

```
## [1] "John"
## [1] "George"
## [1] "Paul"
## [1] "Ringo"
```

or we access the item via indexing

```
for (i in 1:length(beatles)) {
print(i)
print(beatles[i])
}
```

```
## [1] 1
## [1] "John"
## [1] 2
## [1] "George"
## [1] 3
## [1] "Paul"
## [1] 4
## [1] "Ringo"
```

Sometimes it makes sense to construct a nested loop to achieve a particular task.

```
M <- matrix(1:10, 5)
M
```

```
## [,1] [,2]
## [1,] 1 6
## [2,] 2 7
## [3,] 3 8
## [4,] 4 9
## [5,] 5 10
```

We now loop through all rows and columns of the matrix \(\mathbf M\) and print out the value at the index \(\mathbf M[i,j]\).

```
for (i in seq(nrow(M))) {
for (j in seq(ncol(M))) {
val <- M[i, j]
print(paste("row index:", i, "column index:", j, "value:", val))
}
}
```

```
## [1] "row index: 1 column index: 1 value: 1"
## [1] "row index: 1 column index: 2 value: 6"
## [1] "row index: 2 column index: 1 value: 2"
## [1] "row index: 2 column index: 2 value: 7"
## [1] "row index: 3 column index: 1 value: 3"
## [1] "row index: 3 column index: 2 value: 8"
## [1] "row index: 4 column index: 1 value: 4"
## [1] "row index: 4 column index: 2 value: 9"
## [1] "row index: 5 column index: 1 value: 5"
## [1] "row index: 5 column index: 2 value: 10"
```

Exercise: Write a for-loop, that calculates the Fibonacci numbers from the first one to the e.g. 10th!

`### your code here`

```
fib <- c() # empty vector for storing the numbers
k <- 10 # order of last calculated Fibonacci number
fib[1] <- 0 # fib[1] & fib [2] define the first two start numbers
fib[2] <- 1
for (i in 3:k) { # calculate Fibonacci numbers from 3rd position onward
fib[i] <- fib[i - 1] + fib[i - 2]
}
fib
```

`## [1] 0 1 1 2 3 5 8 13 21 34`

**While-loops**

A `while`

loop repeats a task until a condition is met.
This means that we do not need to know in advance how many times the
loop will be executed. Be sure there is a way to exit out of a
`while`

loop, otherwise your program will run forever.

```
i <- 1 # set i to 1
while (i < 10) { # continue as long as i < 10
print(i) # print i
i <- i + 1 # increase i by one for each step
}
```

```
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
```

Other useful commands to control the execution of your code are the
`break`

and the `next`

statement.

We redo the `while`

loop from above, this time however, we
build in an error, which would cause the loop to run infinitely.
However, by introducing the `break`

statement we make sure
the the loop stops no matter what after 50 iterations.

```
i <- 1 # set i to 1
while (i < 10) { # continue as long as i < 10
i <- i - 1 # ERROR! Here we decrease i by one for each step, hence the condition i < 10 is always met!
if (abs(i) == 50) { # if i is 50 or -50 we break out of the loop
print("Iteration stopped!")
break
}
}
```

`## [1] "Iteration stopped!"`

```
# sanity check
print(i)
```

`## [1] -50`

The `next`

statement is used to skip the current loop
execution and restarts the next iteration.

In order to print only even numbers and skip odd numbers of a given
sequence we may write the following code (if you never encountered the
modulo operator `%%`

before, ask your preferred search
engine!):

```
s <- seq(1, 25, 1)
for (i in s) {
if (i %% 2 == 1) { # modulo operator
next
} else {
print(i)
}
}
```

```
## [1] 2
## [1] 4
## [1] 6
## [1] 8
## [1] 10
## [1] 12
## [1] 14
## [1] 16
## [1] 18
## [1] 20
## [1] 22
## [1] 24
```

To conclude this section we apply our knowledge of functions and
control statements to build a small program, called
`guess_a_number`

. The program is all about guessing a random
integer within a given range of guesses.

```
guess_a_number <- function(max_value = 100, number_of_trials = 10) {
## the computer guesses a random number
## between 0 and max_value (default = 100)
vector_of_integers <- seq(1, max_value, 1)
num <- sample(vector_of_integers, 1)
## set trial value to 1
trial <- 1
### utility function to account for user input
## ask user for a guess
ask_for_guess <- function() {
cat("Guess a number between 0 and", max_value, "\n")
guess <- readline(prompt = "Enter an integer: ")
# make sure user entered an integer
if (!grepl("^[0-9]+$", guess)) {
cat("Please provide an integer\n")
return(ask_for_guess())
}
return(as.integer(guess))
}
## start the game
guess <- 101
## set conditions for game over
cat(paste("You have", number_of_trials, "trials to guess the number!\n"))
while (guess != num & trial <= number_of_trials) {
guess <- ask_for_guess()
if (guess == num) {
cat("Congratulations,", num, "is right.\n")
break # break as game is over
} else if (guess < num) {
cat("The number is bigger!\n")
} else if (guess > num) {
cat("The number is smaller!\n")
}
cat(paste(number_of_trials - trial, "trials left!\n\n"))
trial <- trial + 1 # increase the number of trials
}
if (guess != num) {
cat(paste("GAME OVER, the number was", num))
}
}
```

Now copy the code cell above to your R console and give it a try!

`guess_a_number()`

Feel free to adapt the function and play around with the arguments
`max_value`

and `number_of_trials`

.

**Citation**

The E-Learning project SOGA-R was developed at the Department of Earth Sciences by Kai Hartmann, Joachim Krois and Annette Rudolph. You can reach us via mail by soga[at]zedat.fu-berlin.de.

You may use this project freely under the Creative Commons Attribution-ShareAlike 4.0 International License.

Please cite as follow: *Hartmann,
K., Krois, J., Rudolph, A. (2023): Statistics and Geodata Analysis
using R (SOGA-R). Department of Earth Sciences, Freie Universitaet Berlin.*