[R] pass by reference -- how to do it
Simon Fear
Simon.Fear at synequanon.com
Thu Feb 19 15:26:20 CET 2004
I don't disagree - it's just that I once spent a day trying
to work out why my old S-Plus library's <<- didn't work in R
as I thought it should - and then I read the FAQ ...
Especially in interactive work, <<- is very unlikely to cause
a problem. But it's definitely dodgy to trust to this
idiom within a package, say.
Simon
PS also for the record, I stand corrected about S-Plus using <<- to
assign to frame 1; it assigns to database 1. Sorry!
> -----Original Message-----
> From: Gabor Grothendieck [mailto:ggrothendieck at myway.com]
> Sent: 19 February 2004 13:33
> To: Simon Fear; robert_dodier at yahoo.com; andy_liaw at merck.com;
> andy_liaw at merck.com; R-help at stat.math.ethz.ch
> Subject: RE: [R] pass by reference -- how to do it
>
>
> Security Warning:
> If you are not sure an attachment is safe to open please contact
> Andy on x234. There are 0 attachments with this message.
> ________________________________________________________________
>
>
> [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:
>
> > If you are not sure an attachment is safe to open please contact
>
> > 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.
>
> >
>
> > Thanks for your help,
>
> > Robert Dodier
>
>
>
> _______________________________________________
> No banners. No pop-ups. No kidding.
> Introducing My Way - http://www.myway.com
>
Simon Fear
Senior Statistician
Syne qua non Ltd
Tel: +44 (0) 1379 644449
Fax: +44 (0) 1379 644445
email: Simon.Fear at synequanon.com
web: http://www.synequanon.com
Number of attachments included with this message: 0
This message (and any associated files) is confidential and\...{{dropped}}
More information about the R-help
mailing list