Dear useRs, I have a function that creates several global objects with assign("obj",obj,.GlobalEnv), and which I need to run iteratively in another function. The code is similar to f <- function(...) { assign("obj",obj,.GlobalEnv) } fct <- function(...) { for (i in 1:1000) { ... f(...) ...obj... rm(obj) #code fails without this line } } I don't understand why f(), when run in a for() loop inside fct(), does not overwrite the global object 'obj'. If I don't delete 'obj' after I use it, the code fails - the same objects created by the first iteration are used by subsequent iterations. I checked ?assign and the Evaluation chapter in 'R Language Definition' but still don't understand why the above happens. Can someone briefly explain or suggest something I should read? By the way, I don't want to use 'better' techniques (lists, functions that return values instead of creating global objects etc) - I want to create global objects with f() and overwrite them again and again within fct(). Thank you, b.
Do you do anything with "obj" in the elided code? When you say the code fails, do you mean that somewhere it accesses "obj" and doesn't get the version in .GlobalEnv? The line "rm(obj)" removes the copy in the function's environment, so I guess there is a local copy of "obj", otherwise the line would have no effect. If you want the "obj" in .GlobalEnv, you have to ask for it, with "get", unless there are no local copies. More code, or better, a distilled working example, the R version, and platform would be helpful. Reid Huntsinger -----Original Message----- From: r-help-bounces at stat.math.ethz.ch [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of bogdan romocea Sent: Tuesday, January 11, 2005 9:26 AM To: r-help at stat.math.ethz.ch Subject: [R] global objects not overwritten within function Dear useRs, I have a function that creates several global objects with assign("obj",obj,.GlobalEnv), and which I need to run iteratively in another function. The code is similar to f <- function(...) { assign("obj",obj,.GlobalEnv) } fct <- function(...) { for (i in 1:1000) { ... f(...) ...obj... rm(obj) #code fails without this line } } I don't understand why f(), when run in a for() loop inside fct(), does not overwrite the global object 'obj'. If I don't delete 'obj' after I use it, the code fails - the same objects created by the first iteration are used by subsequent iterations. I checked ?assign and the Evaluation chapter in 'R Language Definition' but still don't understand why the above happens. Can someone briefly explain or suggest something I should read? By the way, I don't want to use 'better' techniques (lists, functions that return values instead of creating global objects etc) - I want to create global objects with f() and overwrite them again and again within fct(). Thank you, b. ______________________________________________ R-help at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
I would suggest reading the posting guide, (http://www.r-project.org/posting-guide.html) and give a reproducible example, with the error message that you received. As is, I have no idea what you are doing here, and certainly cannot run this code. You use "..." as an argument to your functions (why I have no idea), but then use "..." within your function seemingly to mean code was omitted rather than using your function argument "...". What "...obj..." means I have no idea. One point though. If the f() function does not take any arguments, then why are you using the special R object "..." as an argument? Furthermore, why not just do the assignment inside of fct() instead of calling another function that just runs code? Please reference the _rest_ of the R Language guide for information on correct usage of "...", especially the chapter on functions, and include a script that can be run from start to finish by anyone at an R prompt without having to decipher what the missing code does, or what the ellipsis is doing in your context. My guess to what I think is going on here is that you are trying to use dynamic scoping, when R uses lexical scoping. If you are an S user, this will be a change. The f() function is stored in .GlobalEnv, so is not aware of any objects stored in the fct() environment. When you run f(), it's looking for an "obj" object in its environment, probably can't find one, and then looking for the "obj" object in the global environment. If it finds it there, it assigns it to itself, basically doing nothing. Once again, the R language guide will explain this. You could solve this by either imbedding the f() function inside of fct(), passing in the obj object, instead of relying on dynamic scoping (which R doesn't use), or probably preferably, not have an f() function at all, as all it does is call another function. Also, I'd reference ?"<<-" for perhaps a cleaner way of doing global assignments. Using this alone may solve your problems, as it may force you to scope your code correctly. -----Original Message----- From: bogdan romocea [mailto:br44114 at yahoo.com] Sent: Tuesday, January 11, 2005 9:26 AM To: r-help at stat.math.ethz.ch Subject: [R] global objects not overwritten within function Dear useRs, I have a function that creates several global objects with assign("obj",obj,.GlobalEnv), and which I need to run iteratively in another function. The code is similar to f <- function(...) { assign("obj",obj,.GlobalEnv) } fct <- function(...) { for (i in 1:1000) { ... f(...) ...obj... rm(obj) #code fails without this line } } I don't understand why f(), when run in a for() loop inside fct(), does not overwrite the global object 'obj'. If I don't delete 'obj' after I use it, the code fails - the same objects created by the first iteration are used by subsequent iterations. I checked ?assign and the Evaluation chapter in 'R Language Definition' but still don't understand why the above happens. Can someone briefly explain or suggest something I should read? By the way, I don't want to use 'better' techniques (lists, functions that return values instead of creating global objects etc) - I want to create global objects with f() and overwrite them again and again within fct(). Thank you, b. ______________________________________________ R-help at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Prof Brian Ripley
2005-Jan-11 17:01 UTC
[R] global objects not overwritten within function
On Tue, 11 Jan 2005, bogdan romocea wrote:> Dear useRs, > > I have a function that creates several global objects with > assign("obj",obj,.GlobalEnv), and which I need to run iteratively in > another function. The code is similar to > > f <- function(...) { > assign("obj",obj,.GlobalEnv) > } > fct <- function(...) { > for (i in 1:1000) > { > ... > f(...) > ...obj... > rm(obj) #code fails without this line > } > } > > I don't understand why f(), when run in a for() loop inside fct(), does > not overwrite the global object 'obj'. If I don't delete 'obj' after I > use it, the code fails - the same objects created by the first > iteration are used by subsequent iterations. > > I checked ?assign and the Evaluation chapter in 'R Language Definition' > but still don't understand why the above happens. Can someone briefly > explain or suggest something I should read? By the way, I don't want to > use 'better' techniques (lists, functions that return values instead of > creating global objects etc) - I want to create global objects with f() > and overwrite them again and again within fct().Since you are not using ... in the sense it is used in R, we have little idea of what your real code looks like and so what it does. Can you please give a small real example that fails. Here is one that works, yet has all the features I can deduce from your non-code: f <- function(x) assign("obj", x, pos=.GlobalEnv) fct <- function() { for(i in 1:2) { x <- i+3 f(x) print(obj) } }> fct()[1] 4 [1] 5> obj[1] 5 -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Apparently the message below wasn't posted on R-help, so I'm sending it again. Sorry if you received it twice. --- bogdan romocea <br44114 at yahoo.com> wrote:> Date: Tue, 11 Jan 2005 17:31:42 -0800 (PST) > From: bogdan romocea <br44114 at yahoo.com> > Subject: Re: [R] global objects not overwritten within functionThank you to everyone who replied. I had no idea that ... means something in R, I only wanted to make the code look simpler. I'm pasting below the functional equivalent of what took me yesterday a couple of hours to debug. Function f() takes several arguments (that's why I want to have the code as a function) and creates several objects. I then need to use those objects in another function fct(), and I want to overwrite them to save memory (they're pretty large). It appears that Robert's guess (dynamic/lexical scoping) explains what's going on. I've noticed though another strange (to me) issue: without indexing (such as obj1 <- obj1[obj1 > 0] - which I need to use though), fct() prints the expected values even without removing the objects after each iteration. However, after indexing is introduced, rm() must be used to make fct() return the intended output. How would that be explained? Kind regards, b. f <- function(read,position){ obj1 <- 5 * read[position]:(read[position]+5) obj2 <- 7 * read[position]:(read[position]+5) assign("obj1",obj1,.GlobalEnv) assign("obj2",obj2,.GlobalEnv) } fct <- function(input){ for (i in 1:5) { f(input,i) obj1 <- obj1[obj1 > 0] obj2 <- obj2[obj2 > 0] print(obj1) print(obj2) # rm(obj1,obj2) #get intended results with this line } } a <- 1:10 fct(a)
This got rejected by SpamCop but I didn't see another reply so am trying again. -----Original Message----- From: Huntsinger, Reid Sent: Wednesday, January 12, 2005 4:29 PM To: 'bogdan romocea'; r-help at stat.math.ethz.ch Subject: RE: [R] global objects not overwritten within function Assigning via <- to "obj1" and "obj2" in fct() creates local copies. In the next iteration "obj1[obj1 > 0]" and "obj2[obj2 > 0]" refer to these local copies, unless you remove them, not the ones in .GlobalEnv, as you intend. You can also use "get" to specify which environment to look in. Reid Huntsinger -----Original Message----- From: r-help-bounces at stat.math.ethz.ch [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of bogdan romocea Sent: Wednesday, January 12, 2005 3:05 PM To: r-help at stat.math.ethz.ch Subject: Re: [R] global objects not overwritten within function Apparently the message below wasn't posted on R-help, so I'm sending it again. Sorry if you received it twice. --- bogdan romocea <br44114 at yahoo.com> wrote:> Date: Tue, 11 Jan 2005 17:31:42 -0800 (PST) > From: bogdan romocea <br44114 at yahoo.com> > Subject: Re: [R] global objects not overwritten within functionThank you to everyone who replied. I had no idea that ... means something in R, I only wanted to make the code look simpler. I'm pasting below the functional equivalent of what took me yesterday a couple of hours to debug. Function f() takes several arguments (that's why I want to have the code as a function) and creates several objects. I then need to use those objects in another function fct(), and I want to overwrite them to save memory (they're pretty large). It appears that Robert's guess (dynamic/lexical scoping) explains what's going on. I've noticed though another strange (to me) issue: without indexing (such as obj1 <- obj1[obj1 > 0] - which I need to use though), fct() prints the expected values even without removing the objects after each iteration. However, after indexing is introduced, rm() must be used to make fct() return the intended output. How would that be explained? Kind regards, b. f <- function(read,position){ obj1 <- 5 * read[position]:(read[position]+5) obj2 <- 7 * read[position]:(read[position]+5) assign("obj1",obj1,.GlobalEnv) assign("obj2",obj2,.GlobalEnv) } fct <- function(input){ for (i in 1:5) { f(input,i) obj1 <- obj1[obj1 > 0] obj2 <- obj2[obj2 > 0] print(obj1) print(obj2) # rm(obj1,obj2) #get intended results with this line } } a <- 1:10 fct(a) ______________________________________________ R-help at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html