Closures are a powerful concept used to create functions between other functions in the R language. This concept helps when we change or repeat one function in the same code and dataset. It also allows a function to retain access to its surrounding environment's variables even after executing the outer function. It enables the function to “close over” or “encapsulate” the variables it needs, creating a self-contained unit of behavior.
In R, closures are often used when we need to create functions with some internal state or configuration, but we don’t want to expose that state to the global environment. Closures are created when we define a function within another function.
A closure consists of a function and the environment in which it was created. The environment contains the local variables and their values.
It encapsulates their state and behavior, which can’t be directly accessed or modified outside the function.
It uses lexical scoping, which means that functions look up variable values in the environment where they were defined, not where they’re called. This is how closures retain access to their parent function’s variables.
The <<-
operator is used to assign a value to a variable in a higher-level (parent) environment.
Here’s an example of a closure to better understand the concept:
# Create a function with name counter to define the closure conceptcounter <- function() {count <- 0# Create another function with name increment in the counter functionincrement <- function() {count <<- count + 1cat("Increment the count:", count, "\n")}# Return the valuereturn(increment)}# Call function and store value in the variablecounter1 <- counter()counter2 <- counter()counter1() # Output: Count: 1counter2() # Output: Count: 1counter1() # Output: Count: 2counter2() # Output: Count: 2counter2() # Output: Count: 3counter1() # Output: Count: 3
Line 2: This creates a function with the name counter
which holds the property of the closure.
Line 3: The count
variable is enclosed within the scope of the counter
function.
Lines 4–8: This creates another function in the counter
function with the name increment
. This function still has access to the count
variable even after counter
has finished executing. Here we use the <<-
operator to store the value in the variable.
Line 10: This returns the function.
Lines 14–15: This calls the counter()
function and stores its value in two different variables.
Lines 17–22: This calls the function where we store the values of the function above to display the output. It allows us to create multiple instances of the counter closure, each with its own independent count.
Free Resources