Components of Function in R Language
Functions in the R Language are objects with three basic components. The components of functions in R language are:
- A formal argument list
- A body
- An environment
Table of Contents
Let us discuss the components of functions in R language in detail.
Formal Argument in R
To learn about Formal argument in R language, see the post formal argument, also see the basics about functions in R Language.
Body of a Function
The body of a function is parsed R statements. The body of a function is usually a collection of statements in braces but it can be a single statement, a symbol, or even a constant.
Environment of a Function
The environment of a function is the environment that was active at the time that the function was created. The environment of a function is a structural component of the function and belongs to the function itself.
A fourth component of a function in R language can be considered as a “Return Value” by a function.
Return Value of a Function
The last object called within a function is returned by the function and therefore available for assignment. Functions can return only a single value but in practice, this is not a limitation as a list containing any number of objects can be returned. Objects can be returned visible or invisible. This option does not affect the assignment side but affects the way results are displayed when the function is called.
y <- function(n){ out <- runif(n) cat (head(out)) invisible(out) }
Functions Closures in R
A function closure or closure is a function together with a referencing environment. Almost all functions in R are closures as they remember the environment where they were created. The functions that cannot be classified as closures, and therefore do not have a referencing environment, are known as primitives.
In R, internal functions are called the underlying C
code. These sum()
and c()
are good cases in point:
environment(sum)
When we call a function, a new environment is created to hold the function’s execution, and normally, that environment is destroyed when the function exists. But, if we define a function g()
that returns a f()
, the environment where f()
is created is the execution environment of g(), that is, the execution environment of g() is the referencing environment of f(). As a consequence, the execution environment of g() is not destroyed as g() exists but it persists as long as f() exists. Finally as f() remembers all objects bound to its referencing environment f() remembers all objects bound to the execution environment of g()
.
We can use the referencing environment of f()
, to hold any of the objects and these will be available to f()
.
g <- function(){ y <- 1 function(x){ x + y } f1 <- g() print(f1) f1(3)
Closures can be used to write functions that in turn closures can be used to generate new functions. This allows us to have a double layer of development: a first layer that is used to do all the complex work in common to all functions and a second layer that defines the details of each function.
f <- function(i){ function(x){ x+i } } f1 <- f(1) f2 <- f(2) f2(4)
By understanding these components, one can effectively create and use functions to enhance one’s R programming.
Note that in R language:
- Functions can be nested within other functions.
- Functions can access variables from the environment where they are defined (lexical scoping).
- R provides many built-in functions for various tasks.
- One can create customized functions to automate repetitive tasks and improve code readability.