# For every fruit there is a loop ... i.e., more on control flow

20 Feb 2020The code we produced in class this week can be downloaded and reviewed here: Code-Day09.R and Code-Day10.R.

This week’s problem set and extra-credit opportunity can be found here:

The big new concept or construct discussed this week was the for-loop. Similar to the `if`

and `else`

constructs, the for-loop allows us to control the flow of operations in R. Whereas the `if`

and `else`

construct allows us to get the computer to do one thing ** if** some condition is

`TRUE`

and another thing **the condition is**

*if*`FALSE`

, the for-loop construct allows us to instruct the computer to repeat a task or calculation as set number of times. This works like so:```
# define object.o as a sequence of integers
object.o <- 1:10
for (element.i in object.o) {
# do something like say
print("Hello") # or
print(element.i) # or
Sys.sleep(time = 2) # go to sleep for 2 seconds
}
```

The above code will instruct the computer to repeat the tasks of printing `"Hello"`

, printing an `element.i`

from the `object.o`

, and sleeping for 2 seconds, 10 times each.

We can use these for-loop constructs for all sorts of tasks that need to be repeated a certain number of times. Say, I need 10 random numbers. We could do the following:

```
rnorm(n = 10, mean = 0, sd = 1) # returns 10 random numbers
# as one vector.
```

Or we could instruct R to give us 1 random number 10 times in a row.

```
for (i in 1:10) {
x <- rnorm(n = 1, mean = 0, sd = 1)
print(x)
}
```

If we ask R to do something once for every element `i`

in a sequence of integers say `1:10`

, we can use the fact that the `i`

s are integers to index vectors and store output in specific locations of some vector. This might look something like this.

```
x <- rep(NA, times = 10) # initiate an empty vector
for (i in 1:10) {
x[i] <- sample(x = letters, size = 1, replace = TRUE)
}
```

In the above code we asked R to pick one random letter from the alphabet (the object `letters`

) and store the random letter in the `i`

th location of the empty `NA`

vector `x`

. At the end of the loop the vector `x`

will contain 10 random letters.

Another use for loops might be the creation of counters (in combination with `if`

and `else`

constructs).

Suppose we wanted to count the number of even numbers in some vector of integers. A for-loop can help solve this problem.

```
random.integers <- sample(x = 1:1000, size = 100, replace = TRUE)
# initiate two counters and set them to zero
even.counter <- 0
odd.counter <- 0
for (i in 1:100) {
if (random.integers[i] %% 2 == 0) {
even.counter <- even.counter + 1
} else {
odd.counter <- odd.counter + 1
}
}
even.counter
odd.counter
```

During class on Wednesday we also reviewed the creation of functions by way of revisiting Problem Set 3. A set of possible responses is reproduced below.

Consider two examples:

#### The min

```
my_min <- function(input) {
output <- sort(x = input, decreasing = FALSE)
return(output)
}
# test my_min() and compare to min()
x <- 10:1
y <- c(0, 1, -1)
z <- rnorm(n = 10, mean = 0, sd = 1)
min(x= x)
min(x= y)
min(x= z)
my_min(input = x)
my_min(input = y)
my_min(input = z)
```

#### The mean

```
my_mean <- function(input) {
ouput <- sum(x = input)/length(x = input)
return(output)
}
```

#### Even vs. odd

```
even <- function(input) {
output <- ifelse(test = input %% 2 == 0,
yes = "even",
no = "odd")
return(output)
}
```

#### Absolute value (Version 1)

```
my_abs <- function(input) {
output <- ifelse(test = input < 0,
yes = input * -1,
no = input)
return(output)
}
```

#### Absolute value (Version 2)

```
my_abs <- function(input) {
output <- sqrt(x = input^2)
return(output)
}
```

#### Median

```
# this version depends on the even() function above
my_median <- function(input) {
n <- length(x = input)
x <- sort(x = input)
if (even(input = n) == "even") {
return(mean(x = x[n/2, n/2 + 1]))
} else {
return(x[ceiling(x = n/2)])
}
}
# test my_median() on even and odd length inputs
# and compare to median()
x <- rnorm(n = 100)
y <- rnorm(n = 101)
median(x = x)
my_median(input = x)
median(x = y)
my_median(input = y)
```