[1] 1 2 3 4 5
[1] 2 3 4 5 6
RaukR 2023 β’ Advanced R for Bioinformatics
27-Jun-2023
By the end of this module, you will:
apply*
functions workpurrr
packagefor
loopsSay, we want to add 1 to every element of a vector:
Let us compare the time of execution of the vectorized version (vector with 10,000 elements):
Function_Call Elapsed_Time_sec Total_RAM_Used_MiB Peak_RAM_Used_MiB
1 vec<-vec+1 0.003 3.8 7.6
is_a_droid <- function(x) {
droids <- c('2-1B', '4-LOM', '8D8', '0-0-0', 'AP-5', 'AZI-3', 'Mister Bones', 'BB-8', 'BB-9E', 'BD-1', 'BT-1', 'C1-10P', 'C-3PO', 'R2-D2')
if (x %in% droids) {
return(T)
} else {
return(F)
}
}
test <- c('Anakin', 'Vader', 'R2-D2', 'AZI-3', 'Luke')
is_a_droid(test)
Error in if (x %in% droids) {: the condition has length > 1
The base::Vectorize
way:
vectorized_is_a_droid <- base::Vectorize(is_a_droid, vectorize.args = c('x'))
vectorized_is_a_droid(test)
Anakin Vader R2-D2 AZI-3 Luke
FALSE FALSE TRUE TRUE FALSE
The apply*
way:
The vapply
:
vapply(test, is_a_droid, FUN.VALUE = TRUE) # value type-safe sapply
vapply(test, is_a_droid, FUN.VALUE = 1)
Anakin Vader R2-D2 AZI-3 Luke
FALSE FALSE TRUE TRUE FALSE
Anakin Vader R2-D2 AZI-3 Luke
0 0 1 1 0
When we explicitly repeat an action using a loop, we talk about iteration. We can also repeat actions by means of recursion, i.e. when a function calls itself. Let us implement a factorial \(!\):
Comparing recursion to iteration is like comparing a phillips head screwdriver to a flat head screwdriver. For the most part you could remove any phillips head screw with a flat head, but it would just be easier if you used the screwdriver designed for that screw right?
Some algorithms just lend themselves to recursion because of the way they are designed (Fibonacci sequences, traversing a tree like structure, etc.). Recursion makes the algorithm more succinct and easier to understand (therefore shareable and reusable)
β StackOverflow
Avoid changing dimensions of an object inside the loop:
_
platform x86_64-pc-linux-gnu
os linux-gnu
major 4
minor 2.3
2023 β’ SciLifeLab β’ NBIS β’ RaukR
Yes, every iteration can be converted to recursion (Church-Turing conjecture) and vice versa. It is not always obvious, but theoretically it is doable. Letβs see how to implement factorial in iterative manner:
More writing for the iterative version, right? What about the time efficiency?
The recursive version:
And the iterative one:
Function_Call Elapsed_Time_sec Total_RAM_Used_MiB Peak_RAM_Used_MiB
1 factorial_iter(1000) 0.003 0 0.1