-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path05-chap5.Rmd
70 lines (50 loc) · 3.67 KB
/
05-chap5.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# Flow of Control {#chap5}
Some programs move in a "linear" fashion, from the first statement, to the second, then third etc. until the end of the program is reached. However, most programs (ie functions) that are longer than 3 or 4 lines tend to allow R to jump around the program from one statement to another, but not in a linear order. For example, we may want to repeat a block of statements a large number of times. Or we may want the program to do different things, depending on the state of some variable in the program.
## Loops
The most common way of iterating over a block of statements is to use a __loop__. In R, there are three commands that provide loops, each with its different use.
## For loops
The most commonly used loop is the _for_ loop. It is used when you want to iterate several statements over the elements of a vector. A simple example:
```{r}
x <- 1:10
for (i in x) {
print(i^2)
}
```
You can see that the function just prints out the square of the numbers from one to ten, one per line. Although it is most common to iterate over integers (``x <- 1:10``), we can iterate over the contents of any vector:
```{r}
for (bed in c("mat", "sofa", "table")) {
cat("The cat sat on the", bed, "\n")
}
```
## while and repeat
The next most commonly used loop is a ``while`` loop. You go around the loop until some condition is not met. Then you exit the loop and go onto the next statement. Here's an example:
```{r}
foo <- function () { ## No arguments!
cat("Values from a Normal distribution\n")
x <- rnorm(1) ## generate a value
while (abs(x) < 1.96) {
cat(x, "\n") ## print x as a side-effect
x <- rnorm(1) ## generate a new value
} ## go around the loop from here.
cat("Outlier detected:", x, "\n") ## another side-effect
}
foo() ## call the function.
```
Note that the loop occurs while the test condition is TRUE. The flow of control breaks out of the while loop as soon as the test condition is FALSE. You can also break out of loops using the ``break`` command. You can also skip an iteration of the loop (usually a for loop) using the ``next`` command.
The ``repeat`` loop is not often used. It simply iterates over a block of code, without the possibility of the loop ending. You can escape from a ``repeat`` loop using the ``break`` or ``next`` commands.
## Branching code: The if-then-else construct.
Frequently we want R to make decisions in our code that depend on some criterion. We want our program to change its behaviour depending on this. This is where the if-then-else construct comes in. Here is a simple example:
```{r}
testcat <- function (animal) {
if (animal == "cat") {
cat("Good kitty.\n")
} else {
cat("What sort of animal are you?\n")
}
}
testcat("cat")
testcat("dog")
```
Here we can see the if-then-else at work. The test criterion is ``if (animal == "cat")`` __then__ do ``cat("Good kitty.\n")`` __else__ do ``cat("What sort of animal are you?\n")``. You can see that you don't actually need to write the ``then``. The if-then-else construct allows us to make programs that branch at one or several places in the code, and execute different blocks of code depending on the test criterion. You can also "chain" if-then-else statements together to test for multiple conditions in the code.
## Conclusion
Now we have the building blocks of an R function: We can assign the function a name, and we tell R it is a function using the ``function`` key word, followed by the arguments to the function. The __main body__ of the function determines how the arguments are to be treated, which may involve loops or if-else constructs. Finally a __value__ is returned by the function. Along the way, the function might have __side-effects__ such as printing to the screen.