C Appendix: Intro to R Programming

In this appendix, we’ll cover the basics of programming in R.

C.1 Numerical vs. Analytical solutions

Just a quick note that sometimes its easier to simulate than to find the analytical solution. And maybe it’s not as elegant not quite as exact, but it can be just as valid for much of the work we’ll do. And sometimes numerical approximation (i.e. simulation) is all we have.

The goal of this appendix is to introduce the basics of how programming in R works, so that at a minimum you can read and understand scripts and functions, or even better, begin to do some programming on your own.

C.2 Useful Functions for Simulation in R

function description
cat() used to print out information
if() beginning of an if-then-else statement, used for program control
for() beginning of a for loop, used for program control
<- function() used to create a new custom function in R
return() often the last command within a function, tells R what value(s) to give back

C.2.1 Printing out results

The cat() statement in R allows me to print something out. I use this for debugging or other information. For example, the following code simply returns the values within (but not including) the quotes:

cat("Hello World!")
## Hello World!

The cat() function can also take variables, commas, “\n” (newline) and more, typically separated by commas. For example:

x <- sample(1:6, 1)
cat("I rolled a", x, "\n")
## I rolled a 5

C.2.2 Guided Practice

  • Modify the above code snippet to print out the sum of rolling two six sided dice.

C.2.3 If Then Statements

The if() and else() statements allow me to do different things depending on a condition. They are part of a set of functions that allow me to control the execution of the program.

For example I could generate a random number and if the number is less than a value do one thing, and if its greater than a value do something different. In the following example, I simulate flipping a fair coin and printing out the results of the flip:

x <- runif(1)   ## generate a random value between 0 and 1

if (x < 0.5) {  ## test if it's less than 0.5
  cat("I flipped Heads")
} else cat("I flipped Tails")
## I flipped Heads

There can also be multiple if-then-else statements in a row to deal with multiple cases. The following illustrates a game where we win on a 1, push on a 2 or 3 and lose on a 4,5, or 6. Note that the code to test whether \(x\le 3\) executes after testing for \(x=1\) so that second clause only tests if \(x =2\) or \(x=3\).

x <- sample(1:6, 1)   ## generate a random value between 0 and 1
cat("roll", x, "\n")
## roll 6
if (x == 1) {  ## test if it's less than 0.5
  cat("I won!")
} else if (x<=3) {
  cat("I pushed")
} else 
  cat("I lost...")
## I lost...

Also note that within if() statements, when testing for equality, you must use a double equal sign as shown above.

C.2.4 Guided Practice

  • Modify the first if-else statement to use a coin that isn’t fair, that has probability of flipping a tails = 0.48
  • Modify the game if-else statement to win on 1 through 3, push on 4 and lose on 5 or 6.
  • Modify the previous game to also print out the amount won, assuming 1 through 3 is +$10, 4 is $0 and 5 or 6 is -$5.

C.2.5 For loops

The for() statement is another control structure that allows me to run a loop a certain number of times. For example, I could add up the numbers 1 through 10 as:

# create storage for the result and initialize this to 0
x <- 0  

# run a loop 10 times, where 'i' starts at 1, increases by 1, and goes up to 10, at which point the loop stops
for (i in 1:10) {
  # add the value of i to the current sum
  x <- x + i
}

# print out the result
cat("total:", x)
## total: 55

C.2.6 Guided Practice

  • Modify the above for loop to add up the first 20 numbers
  • Modify the above for loop to add up the squares of the first 10 numbers (i.e. 1+4+9+…)

C.3 Writing Custom Functions

The function() statement allows me to create a custom function in R. We’ve dealt with a lot of functions so far, and there may be times you want to write your own.

For example, I could write a function that rolls and sums two dice as shown below.

The first line is important. It names the function and tells R what parameters the function has, i.e. what’s listed in the parenthesis. The first example below has no parameters. Then the whole function is enclosed within curly brackets.

# my function is called `sum_two_dice` and doesn't take any parameters  
sum_two_dice <- function() {
  ## roll two die, add them and store in 'rslt'
  rslt <- sample(c(1:6), 1, replace=T)+sample(c(1:6), 1, replace=T) 
  ## return the 'rslt'
  return(rslt)                                                       
}

sum_two_dice() ## need to call the function
## [1] 8

Note that the first bit of code declares the function, AND then to actually execute the function, we need to call it, as shown above.

You can also add parameters to functions to help control how they operate. For example, I could change the example to roll more than two dice, and make the number of dice changeable.

sum_many_dice <- function(ndice) {
  # create storage for the die rolls, where the length is based on the parameter
  rolls <- vector("numeric", ndice)
  # roll ndice 
  rolls <- sample(1:6, ndice, replace=T)
  # sum up the rolls
  total <- sum(rolls) 
  
  # demonstrate the use of if() within a function
  if (total==18) cat("Lucky!")
  
  # return the sum
  return(total)
}

sum_many_dice(3)
## [1] 9

C.3.1 Guided Practice

  • Create your own function that flips a coin a given number of times, and counts and returns the number of Heads. Hint: use the table() function.

C.4 Summary and Review

NOTES:

  • Syntax and spelling are important!
  • Mind the parenthesis and brackets!

So now hopefully you’re starting to feel comfortable with using R for simulation. We’ll do many more examples and soon you’ll be writing your own simple programs.