Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
rworkshop8 [2014/11/02 21:50]
johannabradie [Flow Control]
rworkshop8 [2014/11/03 11: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 55: Line 56:
 <code rsplus> <code rsplus>
 if (2+2)==4 { if (2+2)==4 {
 +print("​Arithmetic works."​) }
 +
 +if (2+1)==4 {
 print("​Arithmetic works."​) } print("​Arithmetic works."​) }
 </​code>​ </​code>​
  
-The 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. +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:
- +
-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 78: Line 80:
 }  # Since all brackets are now closed, R will evaluate the commands. }  # Since all brackets are now closed, R will evaluate the commands.
 </​code>​ </​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>​
 +</​hidden>​
 +
  
 ==== Loops ==== ==== Loops ====
Line 90: Line 155:
 ===for loops=== ===for loops===
  
-The most common loop is the //for loop//​. ​ Use a //for loop// to execute a block of code a known number of times.+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.
  
 **Syntax** **Syntax**
Line 133: Line 198:
 <file rsplus> <file rsplus>
 CO2<​-read.csv("​co2_data.csv"​) 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>​ </​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>​