3

CASE 1:

rm(list = ls())
foo <- function(x = 6){
  set <- function(){
  x <- x*x}
  set()
x}
foo()
# [1] 6

CASE 2:

rm(list = ls())
foo <- function(x = 6){
set <- function(){
  x <<- x*x}
  set()
  x}
foo()
# [1] 36

I read that <<- operator can be used to assign a value to an object in an environment that is different from the current environment. It says that object initialization using <<- can be done to the objects that is not in the current environment. I want to ask which environment's object can be initialized using <<- . In my case the environment is environment of foo function, can <<-initialize the objects outside the function or the object in the current environment? Totally confused when to use <- and when to use <<-.

cryptomanic
  • 5,986
  • 3
  • 18
  • 30
  • The operator `<<-` is sometimes called a deep assignement. It makes a variable and its value that is defined e.g., inside a function available to the entire code. It is R's analogy of a global variable definition. Since the use of global variables are often criticized, many say that using `<<-` is not good practice. – RHertel Sep 17 '15 at 06:39
  • 1
    Discussed here: http://stackoverflow.com/questions/2628621/how-do-you-use-scoping-assignment-in-r – cryo111 Sep 17 '15 at 11:09

2 Answers2

8

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.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
2

The <<- operator can be used to assign a variable to the global environment. It's better to use the assign function than <<-. You probably shouldn't need to use <<- though - outputs needed from functions should be returned as objects in R.

Here's an example

f <- function(x) {
    y <<- x * 2 # y outside the function
}

f(5) # y = 10 

This is equivalent to

f <- function(x) {
    x * 2
}

y <- f(5) # y = 10

With the assign function,

f <- function(x) {
    assign('y', x*2 envir=.GlobalEnv)
}

f(5) # y = 10
nathanesau
  • 1,681
  • 16
  • 27