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
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 ______________________________________________ R-help at stat.math.ethz.ch mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
One needs to be more careful with "<<-" in R than in S-PLUS, because of the scoping rule difference. ?"<<-" says: The operators '<<-' and '->>' cause a search to made through the environment for an existing definition of the variable being assigned. If such a variable is found then its value is redefined, otherwise assignment takes place globally. Note that their semantics differ from that in the S language, but is useful in conjunction with the scoping rules of R. Andy> From: Gabor Grothendieck > > 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 > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html > > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html > >------------------------------------------------------------------------------ Notice: This e-mail message, together with any attachments,...{{dropped}}
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 > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide!http://www.R-project.org/posting-guide.html ______________________________________________ R-help at stat.math.ethz.ch mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html 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}}
[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
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}}