Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between assign() and <<- in R?

The normal approach to writing functions in R (as I understand) is to avoid side-effects and return a value from a function.

contained <- function(x) {
  x_squared <- x^2
  return(x_squared)
}

In this case, the value computed from the input into the function is returned. But the variable x_squared is not available.

But if you need to violate this basic functional programming tenet (and I'm not sure how serious R is about this issue) and return an object from a function, you have two choices.

escape <- function(x){
  x_squared  <<- x^2
  assign("x_times_x", x*x, envir = .GlobalEnv)
}

Both objects x_squared and x_times_x are returned. Is one method preferable to the other and why so?

like image 873
Milktrader Avatar asked Apr 26 '11 02:04

Milktrader


2 Answers

Thomas Lumley answers this in a superb post on r-help the other day. <<- is about the enclosing environment so you can do thing like this (and again, I quote his post from April 22 in this thread):

make.accumulator<-function(){
    a <- 0
    function(x) {
        a <<- a + x
        a
    }
}

> f<-make.accumulator()
> f(1)
[1] 1
> f(1)
[1] 2
> f(11)
[1] 13
> f(11)
[1] 24

This is a legitimate use of <<- as "super-assignment" with lexical scope. And not simply to assign in the global environment. For that, Thomas has these choice words:

The Evil and Wrong use is to modify variables in the global environment.

Very good advice.

like image 156
Dirk Eddelbuettel Avatar answered Oct 09 '22 20:10

Dirk Eddelbuettel


According to the manual page here,

The operators <<- and ->> cause a search to made through the environment for an existing definition of the variable being assigned.

I've never had to do this in practice, but to my mind, assign wins a lot of points for specifying the environment exactly, without even having to think about R's scoping rules. The <<- performs a search through environments and is therefore a little bit harder to interpret.

EDIT: In deference to @Dirk and @Hadley, it sounds like assign is the appropriate way to actually assign to the global environment (when that's what you know you want), while <<- is the appropriate way to "bump up" to a broader scope.

like image 25
John McDonnell Avatar answered Oct 09 '22 21:10

John McDonnell