4 Functions
If you want to make your code more readable and easily understandable, you should split up complicated tasks into more simple ones. A convenient way to do this is defining a function that generalizes a step of your code. If you define this function in advance, you can call it later to perform the task, which might make the code more easily readable and enables you to use paradigmas such as recursion or metaprogramming.
4.1 Function definition
A function definition follows a specific structure.
my_function <- function(argument1, argument2){
# here I describe what I want to do with my arguments
# For example multiply them, assuming that they are numerical.
my_return_value = argument1 * argument2
# and using return() we tell our function what to return
return(my_return_value)
}
my_function(argument1 = 5, argument2 = 7)
## [1] 35
The function can also be called without explicitly naming the arguments, but if you don’t know your code very well, this might lead to difficulties when somebody else or your future self might try to understand the code.
## [1] 10
Another useful feature is the definition of default values for your arguments such that they can be omitted when calling a function.
my_2nd_function <- function(argument1, argument2, greetings = FALSE){
my_return_value <- argument1 * argument2
if(greetings == TRUE){
print("Hello user, the cake is a lie.")
}
return(my_return_value)
}
my_2nd_function(2, 7)
## [1] 14
## [1] "Hello user, the cake is a lie."
## [1] 36
4.2 Recursion
In some settings using a recursive approach instead of loops can create more readable code. In simple terms, recursion in programming is calling a function in its own body. A simple example - even though very inefficient from a computational standpoint - is calculating factorials.
## [1] 3.556874e+14
Often recursion relies on a principle called “divide and conquer”. We test for a simple base case, like n being equal to one in the case of factorials, and otherwise reducing the problem to a more simple one.
Another example is the calculation of Fibonacci numbers using recursion.
fibonacci <- function(n){
if(n == 1 || n == 2) return(1)
else return(fibonacci(n-1) + fibonacci(n-2))
}
fibonacci(20)
## [1] 6765
4.3 Exercises IV
Exercise 1:
Write a function that takes 2 integers as inputs and outputs whether or not the first integer is divisible by the second as a boolean.
Exercise 2:
Try to solve the problem of adding all squares from 1 to n first using loops and then recursion. Think about the underlying way in which the function works. Which approach do you prefer? Why?
Exercise 3:
Write a function that receives a single vector of real numbers as its argument and returns an ordered vector with the same entries.
If you are interested to see recursion in action look for mergesort, that solves this problem with a cool recursive approach.