Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
rworkshop8 [2014/11/03 01:54] johannabradie |
rworkshop8 [2014/11/03 16:18] (current) johannabradie |
||
|---|---|---|---|
| Line 11: | Line 11: | ||
| Download the R script and data for this lesson: | Download the R script and data for this lesson: | ||
| - | -- NEED TO PUT R SCRIPT AND DATA HERE | + | |
| + | [[http://qcbs.ca/wiki/_media/co2_good.csv|CO2 Dataset]] | ||
| Line 25: | Line 26: | ||
| ===== Flow Control ===== | ===== Flow Control ===== | ||
| - | 1. Execute statements **conditionally** using: | + | Flow control allows you to run the same series of commands multiple times and subject to specified conditions. In this section, you will learn how to: |
| - | * if | + | |
| - | * if/else | + | - Execute statements **conditionally** using: if, if/else |
| - | 2. Execute statements **multiple times** using: | + | - Execute statements **multiple times** using: for loops, while loops, repeat loops |
| - | * for loops | + | - **Modify loop** execution using: break statements, next statements |
| - | * while loops | + | |
| - | * repeat loops | + | |
| - | 3. **Modify loop execution** using: | + | |
| - | * break statements | + | |
| - | * next statements | + | |
| ==== if and if/else statements ==== | ==== if and if/else statements ==== | ||
| Line 55: | Line 52: | ||
| </code> | </code> | ||
| - | Curly brackets are used so that R knows that your command is not complete with the first line of code. | + | For example, |
| - | For example, try: | + | <code rsplus> |
| + | if (2+2)==4 { | ||
| + | print("Arithmetic works.") } | ||
| + | |||
| + | if (2+1)==4 { | ||
| + | print("Arithmetic works.") } | ||
| + | </code> | ||
| + | |||
| + | Curly brackets { } are used so that R knows to expect more input. When using brackets, R waits to evaluate the command until the brackets have been closed. If the curly brackets are not used, R may not behave as you are expecting. For example, try: | ||
| <code rsplus> | <code rsplus> | ||
| - | if (2+2)==4 print("Arithmetic works.") | + | if (2+1)==4 print("Arithmetic works.") |
| else print("Houston, we have a problem.") | else print("Houston, we have a problem.") | ||
| </code> | </code> | ||
| Line 70: | Line 75: | ||
| <code rsplus> | <code rsplus> | ||
| if (2+2)==4 { | if (2+2)==4 { | ||
| - | print("Arithmetic works.") | + | print("Arithmetic works.") # R does not evaluate this expression yet because the bracket isn't closed. |
| } else { | } else { | ||
| print("Houston, we have a problem.") | print("Houston, we have a problem.") | ||
| + | } # Since all brackets are now closed, R will evaluate the commands. | ||
| + | </code> | ||
| + | |||
| + | Note that if and if/else test a single condition. If you want to test a vector of conditions (and get a vector of results), you can use ifelse: | ||
| + | |||
| + | For example, | ||
| + | <code rsplus> | ||
| + | a<-1:10 | ||
| + | ifelse(a>5,"yes","no") | ||
| + | </code> | ||
| + | |||
| + | You can also use ifelse in a function to apply a function only under certain conditions: | ||
| + | |||
| + | |||
| + | For example, | ||
| + | <code rsplus> | ||
| + | a<-(-4):5 | ||
| + | sqrt(ifelse(a>=0,a,NA)) | ||
| + | </code> | ||
| + | |||
| + | **Exercise** | ||
| + | |||
| + | <code rsplus> | ||
| + | Paws<-"cat" | ||
| + | Scruffy<-"dog" | ||
| + | Sassy<-cat | ||
| + | animals<-c(Paws,Scruffy,Sassy) | ||
| + | </code> | ||
| + | |||
| + | 1. Use an if statement to print "meow" if Paws is a "cat". | ||
| + | |||
| + | <hidden> | ||
| + | <code rsplus> | ||
| + | if(Paws=="cat") { | ||
| + | print("meow")} | ||
| + | </code> | ||
| + | </hidden> | ||
| + | |||
| + | 2. Use an if/else statement to print "woof" if you supply an object that is a "dog" and "meow" if it is not. Try it out with Paws and Scruffy. | ||
| + | |||
| + | |||
| + | <hidden> | ||
| + | <code rsplus> | ||
| + | if(Scruffy=="dog") { | ||
| + | print("woof") | ||
| + | } else { | ||
| + | print ("meow") | ||
| } | } | ||
| + | |||
| + | if(Paws=="dog") { | ||
| + | print("woof") | ||
| + | } else { | ||
| + | print ("meow") | ||
| + | } | ||
| + | </code> | ||
| + | </hidden> | ||
| + | |||
| + | 3. Use an ifelse statement to display "woof" for animals that are dogs and "meow" for animals that are cats. | ||
| + | |||
| + | <hidden> | ||
| + | <code rsplus> | ||
| + | ifelse(animals=="dog","woof","meow") | ||
| </code> | </code> | ||
| + | </hidden> | ||
| - | When using brackets, R waits to evaluate the command until the brackets have been closed. | ||
| ==== Loops ==== | ==== Loops ==== | ||
| Line 87: | Line 153: | ||
| * iterating a calculation until it converges | * iterating a calculation until it converges | ||
| - | **Syntax** | + | ===for loops=== |
| - | <file rsplus> | + | |
| - | for(variable in sequence) { | + | |
| - | expression } | + | |
| - | while(condition) { | + | The //for loop// is the most common type of loop. Use a //for loop// to execute a block of code a known number of times. |
| - | expression } | + | |
| - | repeat(expression) | + | **Syntax** |
| + | <file rsplus> | ||
| + | for (variable in sequence) { | ||
| + | expression | ||
| + | } | ||
| </file> | </file> | ||
| - | ===for loops=== | + | Each time the series of commands in a loop are executed, it is known as an iteration. |
| - | The most common loop is the 'for loop'. Use a 'for loop' to execute a block of code a known number of times. | + | For example: |
| - | + | ||
| - | **Syntax** | + | |
| <file rsplus> | <file rsplus> | ||
| for (i in 1:5) { | for (i in 1:5) { | ||
| - | expression | + | print(i) |
| } | } | ||
| </file> | </file> | ||
| - | The example above would cause R to evaluate the expression 5 times. In the first iteration, R would replace every instance of i with 1. In the second iteration i would be replaced with 2, and so on. | + | In this example, R will evaluate the expression 5 times. In the first iteration, R will replace each instance of i with 1. In the second iteration i would be replaced with 2, and so on. |
| + | |||
| + | The letter 'i' can be replaced with any letter and the sequence can be almost anything. | ||
| Try: | Try: | ||
| <file rsplus> | <file rsplus> | ||
| - | for (m in 1:10) { | + | for (m in 4:10) { |
| print(m*2) | print(m*2) | ||
| + | } | ||
| + | |||
| + | for (a in c("Hello","R","Programmers")) { | ||
| + | print(a) | ||
| + | } | ||
| + | |||
| + | for (z in 1:30) { | ||
| + | a<-rnorm(n=1,mean=5,sd=2) # draw a value from a normal distribution with mean 5 and sd 2 | ||
| + | print(a) | ||
| } | } | ||
| </file> | </file> | ||
| + | |||
| + | Loops are often used to loop over a dataset. We will use loops to perform functions on a CO2 dataset. | ||
| + | |||
| + | <file rsplus> | ||
| + | CO2<-read.csv("co2_data.csv") | ||
| + | for (i in 1:length(CO2[,1])) { # for each row in the CO2 dataset | ||
| + | print(CO2$conc[i]) #print the CO2 concentration | ||
| + | } | ||
| + | |||
| + | for (i in 1:length(CO2[,1])) { # for each row in the CO2 dataset | ||
| + | if(CO2$Type[i]=="Quebec") { # if the type is "Quebec" | ||
| + | print(CO2$conc[i]) #print the CO2 concentration } | ||
| + | } | ||
| + | } | ||
| + | </file> | ||
| + | |||
| + | The expression part of the loop can be almost anything and is usually a compound statement containing many commands. | ||
| + | |||
| + | <file rsplus> | ||
| + | for (i in 4:5) { # for i in 4 to 5 | ||
| + | print(colnames(CO2[i])) | ||
| + | print(mean(CO2[,i])) #print the mean of that column from the CO2 dataset | ||
| + | } | ||
| + | |||
| + | </file> | ||
| + | |||
| + | Note that this could be done more quickly using apply(), but that wouldn't teach you about loops. | ||
| + | |||
| + | //while loops// and //repeat loops// operate similarly to //for loops//. Once you understand how //for loops// work, you should be able to use any type of loop. You will see some examples of //while loops// and //repeat loops// in the next section. | ||
| + | |||
| + | **Exercise** | ||
| + | |||
| + | NEED TO WRITE IN AN EXERCISE | ||
| + | |||
| + | ==== Loop Modifications ==== | ||
| + | |||
| + | Normally, loops iterate over and over until they finish. To change this behavior, you can use **break** which breaks out of the loops execution entirely, or **next**, which stops executing the current iteration and jumps to the next iteration. | ||
| + | |||
| + | For example, | ||
| + | |||
| + | <file rsplus> | ||
| + | |||
| + | # Print the CO2 concentrations for "chilled" treatments and keep count of how many replications there were. | ||
| + | |||
| + | count=0 | ||
| + | for (i in 1:length(CO2[,1])) { | ||
| + | if (CO2$Treatment[i]=="nonchilled") next #Skip to next iteration if treatment is nonchilled | ||
| + | count=count+1 | ||
| + | print(CO2$conc[i]) | ||
| + | } | ||
| + | print(count) # The count and print command were performed 42 times. | ||
| + | |||
| + | # This could be equivalently written using a repeat loop: | ||
| + | |||
| + | count=0 | ||
| + | i=0 | ||
| + | repeat { | ||
| + | i <- i + 1 | ||
| + | if (CO2$Treatment[i]=="nonchilled") next # skip this loop | ||
| + | count=count+1 | ||
| + | print(CO2$conc[i]) | ||
| + | if (i == length(CO2[,1])) break # stop looping | ||
| + | } | ||
| + | |||
| + | print(count) | ||
| + | |||
| + | ### This could also be written using a while loop: | ||
| + | |||
| + | i <- 0 | ||
| + | count=0 | ||
| + | while (i < length(CO2[,1])) | ||
| + | { | ||
| + | i <- i + 1 | ||
| + | if (CO2$Treatment[i]=="nonchilled") next # skip this loop | ||
| + | count=count+1 | ||
| + | print(CO2$conc[i]) | ||
| + | } | ||
| + | print(count) | ||
| + | </file> | ||
| + | |||
| + | **Exercise** | ||
| + | |||
| + | NEED TO WRITE IN AN EXERCISE | ||
| + | |||
| + | **Using flow control to make a complex plot** | ||
| + | |||
| + | The idea here is that we have a dataset we want to plot, with concentration and uptake values, but each point has a type (Quebec or Mississippi) and a treatment ("chilled" or "nonchilled") and we want to plot the points differently for these cases. | ||
| + | |||
| + | You can read more about mathematical typesetting with ?plotmath, and more about the way # that different colors, sizes, rotations, etc. are used in ?par. | ||
| + | |||
| + | <file rsplus> | ||
| + | |||
| + | head(CO2) # Look at the dataset | ||
| + | unique(CO2$Type) | ||
| + | unique(CO2$Treatment) | ||
| + | |||
| + | # plot the dataset, showing each type and treatment as a different colour | ||
| + | |||
| + | plot(x=CO2$conc, y=CO2$uptake, type="n", cex.lab=1.4,xlab="CO2 concentration", ylab="CO2 uptake") # Type "n" tells R to not actually plot the points. | ||
| + | |||
| + | for (i in 1:length(CO2[,1])) | ||
| + | { | ||
| + | if (CO2$Type[i]=="Quebec"&CO2$Treatment[i]=="nonchilled") { | ||
| + | points(CO2$conc[i],CO2$uptake[i],col="red",type="p") } | ||
| + | if (CO2$Type[i]=="Quebec"&CO2$Treatment[i]=="chilled") { | ||
| + | points(CO2$conc[i],CO2$uptake[i],col="blue") } | ||
| + | if (CO2$Type[i]=="Mississippi"&CO2$Treatment[i]=="nonchilled") { | ||
| + | points(CO2$conc[i],CO2$uptake[i],col="orange") } | ||
| + | if (CO2$Type[i]=="Mississippi"&CO2$Treatment[i]=="chilled") { | ||
| + | points(CO2$conc[i],CO2$uptake[i],col="green") } | ||
| + | } | ||
| + | |||
| + | </file> | ||
| + | |||
| + | **Exercise** | ||
| + | |||
| + | NEED TO WRITE IN AN EXERCISE | ||
| <file rsplus> | <file rsplus> | ||
| </file> | </file> | ||
