Flow controls add efficiency to your code, making it easier to read and saving you time overall
If a condition is TRUE then the code is performed, but if the condition is FALSE then nothing occurs
This can take the form of either a numeric or a logical vector
Numeric
x = 42
x > 0
## [1] TRUE
if(x>0) {
print ("Positive number")
}
## [1] "Positive number"
x = -42
if (x>0) {
print("Positive number")
}
Logical
x = 3
x == 3
## [1] TRUE
if (x == 3){
print ("X is equal to three")
}
## [1] "X is equal to three"
if (x != 3) {
print ("X is not equal to three")
}
else is optional and is only evaluated if conditions to are FALSE
Numerical
x = 42
if (x > 0) {
print("Positive number")
} else {
print ("Negative number")
}
## [1] "Positive number"
y = -42
if (y > 0) {
print("Positive number")
} else {
print ("Negative number")
}
## [1] "Negative number"
Logical condition
x = 42
if (x==3){
print ("X is equal to three")
} else {
print ("X does not equal to three")
}
## [1] "X does not equal to three"
To get even more control from your block of code, you can use else if controls…
If you need more conditions to execute your code, then you can utilize the feature of else if flow control
x = 0
if (x==3){
print ("X is equal to three")
} else if (x == 0){
print ("X is equal to zero")
} else {
print ("I don't know what X is")
}
## [1] "X is equal to zero"
Loops are used in programming to repeat a specific block of code. These include For loops and While loops.
For loops iterate across a sequence of values, repeatedly running code for each value in a list or vector.
Lets say that we want to print out each element in the vector numbers.You would have to copy and paste the same code four times in order to get the results that you want.
numbers <- c(1,2,3,4,6)
print(numbers[1])
## [1] 1
print(numbers[2])
## [1] 2
print(numbers[3])
## [1] 3
print(numbers[4])
## [1] 4
Whereas using the ‘for loops’ you can do the same thing but with much less effort.
for (var in numbers) {
print (var)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 6
You can utilize index within a for loop function as well.
for (var in 1:length(numbers)){
print (numbers[var])
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 6
This type of loop continues to repeat until a specific condition is met and the condition evaluates to FALSE
x <- 1
while (x<6){
print (paste("x is equal to", x))
x <- x + 1
}
## [1] "x is equal to 1"
## [1] "x is equal to 2"
## [1] "x is equal to 3"
## [1] "x is equal to 4"
## [1] "x is equal to 5"
Notice how in the above code I made sure to correct x so that eventually x will be 6 or greater, whereby the while condition will return FALSE and end. If I didn’t do that, the while function would run forever.
Break statements are used to terminate the loop at any chosen iteration.
You can use them in both if statements and for loops
numbers <- c(1,2,4,6)
for (var in numbers){
if (var == 4){
print (paste("The variable 4 should not be there, exiting"))
break
}
print(paste("Values are : ", var))
}
## [1] "Values are : 1"
## [1] "Values are : 2"
## [1] "The variable 4 should not be there, exiting"
This immediately stops the function and it does not continue. However, if it does not encounter the break condition, then the code will continue through.
numbers2 <- c(1,3,5,6)
for (var in numbers2){
if (var == 4){
print (paste("The variable 4 should not be there, exiting"))
break
}
print(paste("Values are : ", var))
}
## [1] "Values are : 1"
## [1] "Values are : 3"
## [1] "Values are : 5"
## [1] "Values are : 6"
But what if we don’t want to stop the code completely? We just want to skip over a part if it doesn’t match our conditions? Thats where ’Next" statements come in.
numbers <- c(1, 2, 4, 6)
for (var in numbers) {
if (var ==4) {
print (paste ("The variable 4 should not be there"))
next
}
print (paste("Values are: ", var))
}
## [1] "Values are: 1"
## [1] "Values are: 2"
## [1] "The variable 4 should not be there"
## [1] "Values are: 6"
What does the following give you?
numbers <- c(1, 2, 4, 6)
for (var in numbers) {
if (var ==4) {
print (paste ("The variable 4 should not be there"))
next
print (paste("Values are: ", var))
}
}
Answer:
## [1] "The variable 4 should not be there"
Functions take an input (argument) and produces an output. R has many functions available to do bioinformatics work.
numbers <-c(1, 2, 4, 6)
print (numbers)
## [1] 1 2 4 6
str(numbers)
## num [1:4] 1 2 4 6
sum (numbers)
## [1] 13
mean (numbers)
## [1] 3.25
These types of functions allow you to manipulate external files into or out of the R environment.
The read.csv function reads in an external table into your R environment
Data.table <- read.csv("Bioinformatics.csv")
The write.csv function writes a data frame or other object into a table that can then be opened with excel or another text editor
my.df <- data.frame(x = 1:5, y = 3:7)
write.csv (my.df, "Bioinformatics_data.csv")
In our previous .csv file that we had, the rows all matched together. But what happens when you read in a file that does not have matching rows/columns?
C_Question2 <- read.csv("ChallengeQuestion2.csv")
Answer:
## ï..Bioinfo Numbers
## 1 1 2
## 2 2 3
## 3 3 4
## 4 3 5
## 5 4 6
## 6 5 6
## 7 6 5
## 8 5 5
## 9 4 6
## 10 6 5
## 11 NA 6
## 12 NA 6
## 13 NA 7
You can also utilize the full power of functions in R by personalizing them to your specific problem. General functions can make your code more clear, and can be easier to maintain that specific code. These can be functions assigned to variables.
Function example
Square_It <- function (x) {
y <- x^2
print(paste("The Square of", x, "is", y))
}
Square_It(5)
## [1] "The Square of 5 is 25"
Square_It(42)
## [1] "The Square of 42 is 1764"
Iterates the functions over elements in a list or a vector (lapply) or over a dataframe (apply). These functions are very similar to a for loop, but can be done in 1 line of code.
3 types of apply functions
Lets say that we have our dataframe:
## x y
## 1 2 1
## 2 5 2
## 3 10 3
## 4 2 4
## 5 3 5
and we want to calculate the mean of each individual row in that dataframe. Lets try it with a for loop.
for (var in 1:nrow(my.df2)) {
mymean= mean(as.numeric(my.df2[var,]))
print(mymean)
}
## [1] 1.5
## [1] 3.5
## [1] 6.5
## [1] 3
## [1] 4
Lets try it with apply instead
apply(my.df2, 1, mean)
## [1] 1.5 3.5 6.5 3.0 4.0
lapply works on vectors or lists, and outputs the results as a list.
x <- sample(1:100, size = 10)
y <- sample(1:100, size = 10)
z <- sample (1:100, size = 10)
lis <- list (x, y, z)
lis_min <- lapply(lis, min)
print(lis_min)
## [[1]]
## [1] 2
##
## [[2]]
## [1] 2
##
## [[3]]
## [1] 6
str(lis_min)
## List of 3
## $ : int 2
## $ : int 2
## $ : int 6
As opposed to lapply, sapply will try to simplify the output of lapply()
Ths will try to output a simple array rather than a list.
x <- sample(1:100, size = 10)
y <- sample(1:100, size = 10)
z <- sample (1:100, size = 10)
lis <- list (x, y, z)
lis_min <- sapply(lis, min)
print (lis_min)
## [1] 2 19 2
str(lis_min)
## int [1:3] 2 19 2
In R, the which() function gives you the position of elements
geneIDs=read.csv("gene_id_to_symbol.csv")
Ensemble = c("ENSG00000121410", "ENSG00000175899","ENSG00000256069", "ENSG00000171428", "ENSG00000156006",
"ENSG00000196136", "ENSG00000114771")
gene_symbol= c("A1BG", "A2M", "A2MP1","NAT1", "NAT2", "SERPINA3", "AADAC" )
entrez=c(1, 2, 3, 9, 10, 12, 13)
mygenes <- data.frame(entrez= entrez, gene_symbol= gene_symbol, Ensemble = Ensemble)
mygenes
## entrez gene_symbol Ensemble
## 1 1 A1BG ENSG00000121410
## 2 2 A2M ENSG00000175899
## 3 3 A2MP1 ENSG00000256069
## 4 9 NAT1 ENSG00000171428
## 5 10 NAT2 ENSG00000156006
## 6 12 SERPINA3 ENSG00000196136
## 7 13 AADAC ENSG00000114771
my_which_function <- which(mygenes$Ensemble == "ENSG00000256069")
my_which_function
## [1] 3
How can the which function be powerful? Because, for example, you can use the output of the which function to return all the values in the row of your search.
mygenessearch <- mygenes[my_which_function,]
mygenessearch
## entrez gene_symbol Ensemble
## 3 3 A2MP1 ENSG00000256069
Homework: Practice problems, and datacamp