# [R] pass by reference -- how to do it

Gabor Grothendieck ggrothendieck at myway.com
Thu Feb 19 14:33:05 CET 2004

```[sorry if this appears twice. I had an email problem and am
sending it out again]

As you and Andy correctly point out, <<- searches through
its environments and it may find a match prior to the Global
Environment.

On the other hand, while its possible to get into trouble,
I believe its actually not that likely since avoiding
nested functions is all you have to do.

For example, we can modify the previous example to make it
NOT work like this. With g nested in f, g's x refers to f's x,
not the global x:

f <- function(x) { g <- function() x[1] <<- x[1]+1; g() } # g nested
x <- 1:5
f(x)
x # x unchanged since x in g matches x in f, not the global x

However, by simply defining g at the top level rather than
nesting it in f2, the code does work to modify the global x
despite the fact that f2 defines its own x:

g <- function() x[1] <<- x[1]+1 # g at not level, i.e. not nested
f2 <- function(x) g()
x <- 1:5
f2(x)
x # c(2,2,3,4,5)

The fact that its this easy to guarantee that it works seems to
be one of the advantages of R's lexical scoping.

---
Date: Thu, 19 Feb 2004 10:11:50 -0000
From: Simon Fear <Simon.Fear at synequanon.com>
To: <ggrothendieck at myway.com>, <robert_dodier at yahoo.com>, <r-help at stat.math.ethz.ch>
Subject: RE: [R] pass by reference -- how to do it

For the record, be careful: <<- does not necessarily assign to
the global environment. In R ` x <<- value` assigns `value` to
the first instance of `x` it can find using lexical scoping. Only if it
doesn't find any such variable, it will indeed create an `x`
in .GlobalEnv.

Tricky for those brought up on S-Plus, where assignment <<-
is guaranteed to assign to frame 1.

HTH

> -----Original Message-----
> From: Gabor Grothendieck [mailto:ggrothendieck at myway.com]
> Sent: 18 February 2004 04:19
> To: robert_dodier at yahoo.com; r-help at stat.math.ethz.ch
> Subject: RE: [R] pass by reference -- how to do it
>
>
> Security Warning:
> Andy on x234. There are 0 attachments with this message.
> ________________________________________________________________
>
>
>
> If you don't mind NOT passing your arrays at all then you
> can do this:
>
> f <- function() a[1] <<- a[1] + 1
> a <- 1:5
> f() # increments first element of a by 1
> a # c(2,2,3,4,5)
>
> The <<- causes the expression to take place in the global
> environment.
>
> If you want to actually pass your arrays by reference then the
> following works although its a bit messy:
>
> g <- function(z) eval(eval(substitute(expression(z[1] <<- z[1]+1))))
> a <- 1:5
> g(a) # increments first element of a by 1
> a # c(2,2,3,4,5)
>
> The <<- causes the expression to be evaluated in the global
> environment. expression() turns its argument into an object
> of mode expression. substitute() replaces z with the argument
> passed to f in that expression and returns an object of mode
> call. The inner eval turns the object of mode call into an
> object of mode expression and the outer eval evaluates that
> expression.
>
> ---
> Date: Tue, 17 Feb 2004 13:23:58 -0800 (PST)
> From: Robert Dodier <robert_dodier at yahoo.com>
> To: <r-help at stat.math.ethz.ch>
> Subject: [R] pass by reference -- how to do it
>
>
> Hello,
>
> Pass by reference appears to be a topic which comes up
> from time to time, but I wasn't able to find something in
> the R-help archives which tells how to accomplish it.
>
> I have a problem that you may have seen before -- R runs
> out of memory when processing large matrices. Part of the
> problem for me is that I am using some large matrices as
> function arguments, and these are modified, which leads
> to allocating copies of the matrices.
>
> I would like to do the modification "in place" so that
> a copy is not required. Thanks for any light you can shed
> on this.
>
> If you're tempted to tell me "you don't really want to do that" --
> let me save you the trouble. You are so very right! Indeed I
> don't want to have pass by reference variables. OTOH I don't
> want R to come to a dead halt at an inconvenient time either.
>
> Robert Dodier

```