260 likes | 371 Views
R basics workshop. J. Sebasti án Tello Iván Jiménez. Center for Conservation and Sustainable Development Missouri Botanical Garden. 9 . Flow Control. F low control lets you define how your scripts run.
E N D
R basics workshop J. Sebastián Tello Iván Jiménez Center forConservation and SustainableDevelopment Missouri Botanical Garden
Flow control letsyou define howyour scripts run • There are a number of constructs in R thatallowyouto control theflow of thecode • There are mainly 3 types: • Loops – for, while, repeat • Breaking points – break, next • Conditionals – if, else and ifelse • Wewillfocuson: for, while and if • Forhelp: ?Control
“for” loops • A loop is the repetition of a piece of code “n” times • for is the most common construct to create loops • This is the general structure of a “for” loop: for(i in v) { code… } Tab/space Which means: For each value that i takes from vector v, repeat: { this code }
“for” loops • Easy example 1: v <- 1:10 for(i in v) { print(i) } Which means: The vector v has values from 1 to 10 every 1 For each value that itakes from vectorv, repeat: print the value of i into the screen
“for” loops • Easyexample 2: v<- letters v for(i in v) { print(i) }
“for” loops • Easyexample 3: v<- letters length(v) result <- 0 for(i in v) { print(i) result<- result+ 1 } result
“for” loops • Easyexample 4: v <- c(1,3,5,2,4) result <- 0 for(i in 1:length(v)) { print( c(i, v[i]) ) result <- result + v[i] } result
“for” loops • Easyexample 5: col.v <- rainbow(100) cex.v <- seq(1, 10, length.out=100) plot(0:1, 0:1, type="n") for(i in 1:200) { print(i) points(runif(1), runif(1), pch=16, col=sample(col.v, 1), cex=sample(cex.v, 1)) Sys.sleep(0.1) }
“for” loops • Open the file “BatsEnviroAmerica.txt” BatData <- read.table(file=file.choose(), header=TRUE, sep="\t") Or if the files is in your working directory: BatData <- read.table(file="BatsEnviroAmerica.txt", header=TRUE, sep="\t")
“for” loops • Open the file “BatsEnviroAmerica.txt” class(BatData) names(BatData) rich <- BatData$richness enviro <- BatData[,5:ncol(BatData)] enviro[1:5, ]
“for” loops LM.R2 <- rep(NA, ncol(enviro)) LM.R2 for(i in 1:ncol(enviro)) { LM.i <- lm(rich ~ enviro[,i]) res.LM.i <- summary(LM.i) LM.R2[i] <- res.LM.i$adj.r.squared } LM.R2
“for” loops LM.R2 names(LM.R2) <- names(enviro) barplot(LM.R2)
“while” loops • while is sometimes also very useful • This is the general structure of a “while” loop: while(condition) { code… } Which means: While this condition is TRUE, repeat: { this code }
“while” loops • Easy example 1: v <- 1:10 for(iin v) { print(i) } v <- 1:10 i <- 0 while(i < max(v)) { i <- i+1 print(i) }
“while” loops • Easy example 1: i <- 0 while(i < max(v)) { i <- i+1 print(i) } v <- 1:10 Version 1 i <- 0 while(i < max(v)) { print(i) i <- i+1 } Version 2
“while” loops • Easy example 2: Bp <- 0.1;Dp <- 0.1;Np <- 1-Bp-Dp max.t <- 100; time <- 0; abund<- 10 plot(c(0, max.t), c(0, 100), type="n") while(abund>0 & time<= max.t) { change <- sample(c(-1,0,1), size=abund, prob=c(Dp, Np, Bp), replace=TRUE) abund <- abund + sum(change) time <- time + 1 points(time, abund, pch=16, col="black") }
“if” condition • if controls the flow by allowing code to run only if a condition is met • Easy example 1: v <- 1:10 for(i in v) { print(i) if(i == 5) print("Reached 5") }
“if” condition and “break” • if controls the flow by allowing code to run only if a condition is met • Easy example 1: v <- 1:10 for(i in v) { print(i) if(i == 5) { print("Reached 5") break() } }
“if” condition trait<- 0; max.time <- 100 plot(c(0,max.time), c(-20, 20), type="n", ylab="Trait Value", xlab="Time") points(0, trait, pch=16, col="black") for(i in 1:max.time) { trait.shift <- rnorm(1, 0, 0.5) trait<- trait+ trait.shift if(trait.shift> 0) COL <- "gold" if(trait.shift< 0) COL <- "lightblue" points(i, trait, pch=16, col=COL) Sys.sleep(0.2) }
Avoiding loops • Loops are extremely useful, but slow. When possible, avoid them. • Often, you will be working with large data sets. Lets simulate a matrix of 50 species abundances in 1,000,000 sites M <- matrix(rpois(50000000, 10), ncol=50) M[1:5,] dim(M)
Avoiding loops • How to calculate the number of individuals at each site (sum by rows)? • Option 1 – a ‘for’ lool abund.1 <- numeric() system.time( { for(iin 1:nrow(M)) { abund.1 <- c(abund.1, sum(M[i,])) } })
Avoiding loops • How to calculate the number of individuals at each site (sum by rows)? • Option 2 – a better ‘for’ lool abund.2 <- rep(NA, nrow(M)) system.time( { for(iin 1:nrow(M)) { abund.2[i] <- sum(M[i,]) } })
Avoiding loops • How to calculate the number of individuals at each site (sum by rows)? • Option 3 – use a function of the family ‘apply’ system.time( { abund.3 <- apply(M, 1, sum) }) ?apply
Vectorization • How to calculate the number of individuals at each site (sum by rows)? • Option 4 – Vectorize!Use a built-in function in R that was written in other code (e.g., C, C++, Fortran) system.time( { abund.4 <- colSums(M) })
Exercise 9 Flow Control