- Homework is due Friday
- We will not be meeting on Friday
- Read The Art of R Programming (Chapter 7)
Patrick D. Schloss, PhD (microbialinformatics.github.io)
Department of Microbiology & Immunology
for
loops over a range of variables...for(i in 1:10){
# do something clever
}
1:10
is a vectorfor
loops over a vector...x <- seq(2,100,2)
for(i in x){
# do something clever...
}
or
x <- c("red", "green", "blue")
for(i in x){
# do something clever...
}
for(i in 10:1){
i
}
print("blast off!")
## [1] "blast off!"
Hmmm. What went wrong?
Within a loop (or any function) you have to explicitly tell R to output the value of a variable
for(i in 10:1){
print(i)
}
print("blast off!")
## [1] 10
## [1] 9
## [1] 8
## [1] 7
## [1] 6
## [1] 5
## [1] 4
## [1] 3
## [1] 2
## [1] 1
## [1] "blast off!"
for(i in 1:10){
squares[i] <- i^2
}
## Error in squares[i] <- i^2: object 'squares' not found
squares
## Error in eval(expr, envir, enclos): object 'squares' not found
What's wrong?
Have to create vector before starting loop:
squares <- vector()
for(i in 1:10){
squares[i] <- i^2
}
squares
## [1] 1 4 9 16 25 36 49 64 81 100
Have to create vector before starting loop:
squares <- rep(NA, 10)
#squares <- rep(0, 10)
for(i in 1:9){
squares[i] <- i^2
}
squares
## [1] 1 4 9 16 25 36 49 64 81 NA
x<-c(5,12,13)
for(i in x) { print(x^2) }
for(i in x) { print(i^2) }
x<-c(5,12,13)
for(i in x) { print(x^2) }
## [1] 25 144 169
## [1] 25 144 169
## [1] 25 144 169
for(i in x) { print(i^2) }
## [1] 25
## [1] 144
## [1] 169
while
loops...i<-1
while(i <= 10){
print(i)
}
Notice anything wrong with this statement?
while
loopsYou have to modify the index within the loop because i
will always be less than or equal to 10:
i<-1
while(i <= 10){
i<-i+3
print(i)
}
break
-ing while loopsbreak
command breaks you out of the current loopfor
and repeat
loopsx<-0;
while(TRUE){
x<-rnorm(1);
print(x)
if(x<0){ break }
}
repeat
loops...x<-0;
repeat {
x<-rnorm(1);
print(x)
if(x<0){ break }
}
## [1] 1.258434
## [1] 0.1496421
## [1] -0.6827691
next
...counter <- 0
while(counter < 10){
x<-rnorm(1);
if(x<0){ next }
print(x)
counter <- counter+1
}
## [1] 0.3141362
## [1] 0.4966642
## [1] 0.9285402
## [1] 2.262056
## [1] 0.3757543
## [1] 1.150501
## [1] 0.09672476
## [1] 1.104058
## [1] 1.085318
## [1] 0.5036225
squared[i] <- i^2
i^2
clearly costs some unit of time, but look at the "squared[i] <-" part. squared <- "[<-"(squared,i,value=i^2)
<-
part is a function!squared
is being made, element i
is changed to i^2
and the resulting vector is reassigned to squared
. The end result is to
re-assign the entire vector because you changed one value.squared <- (1:10)^2
metadata
tableifelse
ifelse
from Excel? It's the same in R...ifelse(LOGICALTEST, Do this if TRUE, Do this if FALSE)
x <- seq(1, 100, 5)
ifelse(x>40, "old", "young")
## [1] "young" "young" "young" "young" "young" "young" "young" "young"
## [9] "old" "old" "old" "old" "old" "old" "old" "old"
## [17] "old" "old" "old" "old"
x <- seq(1, 100, 5)
ifelse(x<10, "kid", ifelse(x<20, "adolscent", "adult"))
## [1] "kid" "kid" "adolscent" "adolscent" "adult"
## [6] "adult" "adult" "adult" "adult" "adult"
## [11] "adult" "adult" "adult" "adult" "adult"
## [16] "adult" "adult" "adult" "adult" "adult"
if... else if...else
for(age in x){
if(age < 10){ #age has to be an atomic varaible
print("kid")
} else if(age<20) {
print("adolescent")
} else {
print("ancient")
}
}
## [1] "kid"
## [1] "kid"
## [1] "adolescent"
## [1] "adolescent"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"
## [1] "ancient"