The operator <<-
is the parent scope assignment operator. It is used to make assignments to variables in the nearest parent scope to the scope in which it is evaluated. These assignments therefore "stick" in the scope outside of function calls. Consider the following code:
fun1 <- function() {
x <- 10
print(x)
}
> x <- 5 # x is defined in the outer (global) scope
> fun1()
[1] 10 # x was assigned to 10 in fun1()
> x
[1] 5 # but the global value of x is unchanged
In the function fun1()
, a local variable x
is assigned to the value 10
, but in the global scope the value of x
is not changed. Now consider rewriting the function to use the parent scope assignment operator:
fun2 <- function() {
x <<- 10
print(x)
}
> x <- 5
> fun2()
[1] 10 # x was assigned to 10 in fun2()
> x
[1] 10 # the global value of x changed to 10
Because the function fun2()
uses the <<-
operator, the assignment of x
"sticks" after the function has finished evaluating. What R actually does is to go through all scopes outside fun2()
and look for the first scope containing a variable called x
. In this case, the only scope outside of fun2()
is the global scope, so it makes the assignment there.
As a few have already commented, the <<-
operator is frowned upon by many because it can break the encapsulation of your R scripts. If we view an R function as an isolated piece of functionality, then it should not be allowed to interfere with the state of the code which calls it. Abusing the <<-
assignment operator runs the risk of doing just this.