How to create functions in R?
I started working on several projects which because of their similarities require me to run one or more times the same code, which meant copying and pasting multiple times it. While this type of practice is something that is usually done every day, implies a certain level of risk and can lead to unwanted errors due to distraction or carelessness.
The most logical way to treat a set of code that always runs with the same input value involves working with functions: creation and invocation of functions.
If you already have the basic knowledge about functions, I recommend reading this book from Advance R de Hadley Wickham to goes deep on this issue.
What is a function
A function is a set of lines of code that perform a specific task and can return a value.
So, functions can receive and return parameters.
They can be passed as arguments to other functions, as well as they can be nested. This means that I can define a function within another function.
The return value of a function is the last expression in the body of the function to be evaluated.
Syntax of a function in R
Functions are created using the function () directive and stored as R objects like any other object. Being more specific, they are R objects of class “function”.
f <- function()
{ ## Just do something when I call you}
Why we want to create functions?
Because it’s a way to minimize the amount of errors we can have by using the same code over and over again. Because it simplifies the resulting code.
Because they are a way to solve big problems first by breaking these same big problems down into simple tasks. Let’s go with some examples, starting with examples of less complexity until we reach those that have more complexity.
How to create a (very) simple function
# Define a simple function
myFunction<-function(n)
{
n+1
}
# Assign `10` to `var`
var <- 10
# Call function
m <- myFunction (var)
How to call a function from another file
Both files must be in the same directory or, failing that, in the call made in source
File with functions, let’s call it: File A
# Funcion simple
miPrimerFuncion<-function(n)
{
n+1
}
File B calling to the function including into File A
source("funciones.R")
var <- 11
m <- miPrimerFuncion (var)
m
Error messages within functions
Writing code imply that the code that we want produce is high quality code, legible, clear, besides doing what it is supposed to do. One step in that direction is to include error messages within the functions.
Simple error messages
# Define a simple function
myFirstFunction<-function(n)
{
stopifnot(is.numeric(n))
n+1
}
Specific error messages
# Define a simple function
myFirstFunction<-function(n)
{
if (!is.numeric(n)) {
stop("This function only accepts numerical input values. Try again.")
}
n+1
}
Practical considerations when using functions
The functions must live in memory first, to be able to be called, that means: first we execute the code where the function is defined and, later we can make any call to it, otherwise just we get an error message.
Names for variables and functions
It is recommended as good practice to include descriptive names of the objective of the function we are developing. That allow us to easily understand what the function does, makes it easier for us to understand our code, and also to share our code with others.
KM_to_Miles<-function(n)
{
if (!is.numeric(n)) {
stop("This function only accepts numerical inputs. Try again.")
}
n*1.609344
}
It is a little hard understand the next piece of code:
Conversion<-function(Something)
{Something*1.609344 }
Validations on the arguments
Verifying that the arguments received correspond with respect to the class we are waiting for, allows us to ensure that the final result is in line with expectations.