In this article, you will learn how to write your own functions in R. Specifically, we will cover:
- How to write a simple function
- How to write a more complex function
- How to write an anonymous function
- How to write a function with an unfixed number of arguments
- How to write a recursive function
1. Writing a simple function
Let’s define a new function divide that takes 2 arguments a and b and returns a / b:
divide = function(a, b) {
a / b
}
# divide(1, 1) returns: 1
# divide(1,2) returns: 0.5
# divide(a = 1, b = 2) also returns: 0.5
Normally, a function returns the last expression written inside the curly braces: { }. (In our example above, the last written expression inside the function is: a / b)
If you want, you can choose to return another value by using return(). This will force the function to stop and return the expression inside of return().
For example:
divide = function(a, b) {
return(a - b) # stop and return a - b
a / b # this line will be ignored
}
# divide(1, 1) returns: 0
# divide(1,2) returns: -1
2. Writing a more complex function
We can expand our function to check whether the user’s inputs are numbers; If not, the function should return an error message.
We can return error messages by using stop():
divide = function(a, b) {
# checking if a or b are not numeric values
if (!is.numeric(a) || !is.numeric(b)) {
stop("The function expects numeric values")
}
else {
a / b
}
}
# divide(1, 'x') returns: Error in divide(1, "x") : The function expects numeric values
# divide(1, 1) returns: 1
# divide(1,2) returns: 0.5
Our function still has a obvious problem:
The current version of divide outputs Inf when we divide by zero.
divide(1, 0) # outputs: Inf
So, we can use warning() to return a warning message when the users tries to divide by zero.
Note that here we are returning a warning not an error because the division by zero can be executed (after all, R does return an answer: Inf), but the answer may not be anticipated by the user.
divide = function(a, b) {
# checking if a or b are not numeric values
if (!is.numeric(a) || !is.numeric(b)) {
stop("The function expects numeric values")
}
# if b is 0, return an error message
else if (b == 0) {
warning("Division by zero")
}
else {
a / b
}
}
# divide(3, 0) outputs: Warning message:
# In divide(1, 0) : Division by zero
3. Writing an anonymous function
An anonymous function provides a shortcut to write a simple function. Since the anonymous function has no name, it cannot be referenced/used elsewhere in the code.
The syntax is:
function(input) output
For example:
sapply(c(1,2,3), function(x) 1/x) # sapply applies the anonymous function to c(1,2,3) # and outputs: 1.0000000 0.5000000 0.3333333
But, we still have a problem when we divide by zero:
sapply(c(1,2,3,0), function(x) 1/x) # outputs: 1.0000000 0.5000000 0.3333333 Inf
So, we can include an if-else statement inside the anonymous function to handle division by zero as follows:
sapply(c(1,2,3,0), function(x) {if (x != 0) 1/x else NA})
# outputs: 1.0000000 0.5000000 0.3333333 NA
4. Writing a function with an unfixed number of arguments
We can use the 3 dots to specify that a function takes an undetermined number of arguments.
For example:
add = function(...) {
sum(...)
}
# add(1,2,3) returns: 6
# which is: 1 + 2 + 3
You can pass the “…” argument to another function inside of your function.
For example:
random.plot = function(n_points, ...) {
x = 1:n_points
y = rnorm(n_points)
plot(x, y, ...)
}
set.seed(1)
random.plot(100)
Output:

So when we specify col = “red”, it will be passed to the function plot inside of our custom function:
set.seed(1) random.plot(100, col = 'red')
Output:

5. Writing a recursive function
A recursive function is a function that calls itself (i.e. defined in terms of itself).
For example:
factorial = function(n) {
# if n is 0 or 1, the answer is 1
if (n == 0 || n == 1) {
return(1) # done
}
# else the function will continue calling itself
# each time with a smaller n,
# until we get to n = 1
else {
return(n * factorial(n-1)) # recursive call
}
}
# factorial(3) outputs: 6
Here’s an illustration that represents how the function works when we call factorial(3):
