In this tutorial we look at how to write functions in R.
What are functions?
- They contain lines of code enclosed within a body. The variable defined and declared inside the body are not available outside the body unless especially specified by a return statement. Example
- In R, an explicit return statement is not required. The last variable evaluated is returnedExample
- The function definition defines one or more variables that can be passed by the caller of the function.Example
- The function can return an object or a list.Example
- The variables passed to the R function are normally passed by value. i.e. a copy of the object is passed, so if you change the object inside the function, the change is not reflected outside the function.Example
- The R.oo package provides ways to pass arguments by values.
- R follows principles of functional programming. You can assign functions to a variable and pass functions as arguments to other functions.Example
- R functions do not require a name. They can be anonymous.Example
- R supports closures. closures are function that can access variables from its enclosing environment.Example
Example – function without arguments and scope
functionName <- function(argumentA, argumenB) { #function Body return(varc); }
In this example we create a function that does not accept any arguments. The function prints todays date. The example also creates a local variable and demonstrates how that local variable is not accessible outside the function.
> printDate <- function(){todaysDate = Sys.Date(); print(todaysDate)} > printDate() [1] "2016-02-06" > todaysDate Error: object 'todaysDate' not found
The variable todaysDate is defined inside the function body and is therefore not available outside the function.
Example – No explicit return, last variable returned
> printDate <- function(){todaysDate = Sys.Date(); todaysDate;} > printDate() [1] "2016-02-08"
An explicit return() is also possible, but its slightly faster if you don’t use a return statement. Of course, some developers may find code more readable if it there is a return statement.
> fun <- function(a,b){return ((a+b)^b)} > fun(1,2) [1] 9
Examples – Functions with parameters
-
Functions having parameters with default value.
> fun <- function(a,b=1){(a+b)^b} > fun(2) [1] 3
In the example below we did not specify b since it has a default value of 1.
-
Calling a function with named arguments
> fun <- function(a,b=1){(a+b)^b} > fun(b=2,a=3) [1] 25
In the example above we call the function by specifying the name of the arguments. Note that when we specify names the order is no longer important. You can also do this:
> fun(b=2,3) [1] 25
we specified the name of only one argument, R figured out the other argument. Here’s an interesting case
> fun < - function(a,b,c){cat("a:",a,",b:",b,",c:",c,'\n')} > fun(b=1,2,3) a: 2 ,b: 1 ,c: 3
We specified b by name and then two variables without name and R assigned them.
Example – return object or list
Here’s a really dumb function that just returns a data frame.
> fun <- function(a,b) { data.frame(a=c(1,2,3),b=c(4,5,6)) } > fun() a b 1 1 4 2 2 5 3 3 6
and another that returns a list (of the data frame that we created above.)
> fun <- function(a,b) { list(data.frame(a=c(1,2,3),b=c(4,5,6))) } > fun() [[1]] a b 1 1 4 2 2 5 3 3 6
Example – pass by value.
> a=2 > fun <- function(a) {a=a^2;a} > fun(2) [1] 4 > a [1] 2
We create a variable a and assign 2 to it. we modified that variable and changed it to 4 however when we exit the function a is still 2. Works for a list too
> a=list(1,2) > fun <- function(a) {a[1]=3;a} > fun(a) [[1]] [1] 3 [[2]] [1] 2 > a [[1]] [1] 1 [[2]] [1] 2
Example – Creating and passing functions
We create a slightly simplistic example to explain passing functions.
Step 1 is the create two functions
> funa <- function(a,b){a+b} > funb <- function(a,b){a*b} > func <- function(c,d,e){d+c(e)}
The function c takes in 3 arguments. The first is a ‘function’, the next two are numbers
> func(funa,1,2) # 1 + (1+2) [1] 4 > func(funb,1,2) # 1 + (1*2) [1] 3
Example – Anonymous function
In this example we demonstrate an anonymous function. We continue with the example above, but instead of passing in a function we create a function
> func(function(x,y){x+y},1,2) [1] 4
We created a function inline and passed it the func. The function does not have a name.