[R] scoping rules
Can someone help me with this simple example? sq - function() { y - x^2 y } myfunc - function() { x - 10 sq() } myfunc() executing the above in R yields: myfunc() Error in sq() : Object x not found I understand that R's scoping rules cause it to look for x in the environment in which sq was defined (the global environment in this case). But in this case x is defined inside the calling function, not the environment in which sq was defined. Is there a way to tell R to look in the calling function for x ? I have tried the following variants of eval such as eval(sq(),parent.frame()) with no success. Thanks for your help. Regards, Whit R.Version() $platform [1] i386-pc-mingw32 $arch [1] i386 $os [1] mingw32 $system [1] i386, mingw32 $status [1] $major [1] 1 $minor [1] 9.1 $year [1] 2004 $month [1] 06 $day [1] 21 $language [1] R __ [EMAIL PROTECTED] mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Re: [R] scoping rules
On Thu, 9 Sep 2004 12:01:56 -0400 , Whit Armstrong [EMAIL PROTECTED] wrote : Can someone help me with this simple example? sq - function() { y - x^2 y } myfunc - function() { x - 10 sq() } myfunc() executing the above in R yields: myfunc() Error in sq() : Object x not found I understand that R's scoping rules cause it to look for x in the environment in which sq was defined (the global environment in this case). But in this case x is defined inside the calling function, not the environment in which sq was defined. Is there a way to tell R to look in the calling function for x ? The easiest (and best) is to pass x as an argument to sq. Duncan Murdoch __ [EMAIL PROTECTED] mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
[R] nls and R scoping rules
I apologize for posting this in essence the second time (no light at the end of the tunnel yet..): is there a way to enforce that nls takes both, the data *and* the model definition from the parent environment? the following fragment shows the problem. # cut here== wrapper - function (choose=0) { x - seq(0,2*pi,len=100) y - sin(1.5*x); y - rnorm(y,y,.1*max(y)) if (choose==0) { rm(fifu,pos=1) fifu - function(w,x) {sin(w*x)} } else assign('fifu',function(w,x) {sin(w*x)},.GlobalEnv) res - nls(y ~ fifu(w,x),start=list(w=1)) res } # cut here== if called as wrapper(1) this runs fine because the fitting function fifu is assigned in the GlobalEnv. if called as wrapper(0), fifu is defined only locally and nls (actually, nlsModel, I think) does not know what I'm talking about. I understand, the problem is that the scoping rules are such that nls does not resolve 'fifu' in the parent environment, but rather in the GlobalEnv. (this is different for the data, which *are* taken from the parent environment of the nls-call). I tried some variants of using eval but without starting to modify nls itself there seems no way (up to now, anyway). The solution to assign 'fifu' directly into the GlobalEnv does work, of course, but leads to the undesirable effect of accumulating objects in the workspace which are not needed there (and might overwrite existing ones). in response to my first post, I got the hint that for lm the situation is different: it handles the above situation as desired (i.e. accepts local model definition). in so far one might even argue that this behaviour of lm and nls leads to an inconsistent behaviour of R in quite similar situations (e.g. replacing at some point a linar model by a nonlinear model in some large project is not achieved by simply replacing lm by nls somewhere deep down in the source code). regards, joerg __ [EMAIL PROTECTED] 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 __ [EMAIL PROTECTED] 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
Re: [R] nls and R scoping rules
On Thu, 10 Jun 2004, joerg van den hoff wrote: I apologize for posting this in essence the second time (no light at the end of the tunnel yet..): is there a way to enforce that nls takes both, the data *and* the model definition from the parent environment? the following fragment shows the problem. # cut here== wrapper - function (choose=0) { x - seq(0,2*pi,len=100) y - sin(1.5*x); y - rnorm(y,y,.1*max(y)) if (choose==0) { rm(fifu,pos=1) fifu - function(w,x) {sin(w*x)} } else assign('fifu',function(w,x) {sin(w*x)},.GlobalEnv) res - nls(y ~ fifu(w,x),start=list(w=1)) res } # cut here== if called as wrapper(1) this runs fine because the fitting function fifu is assigned in the GlobalEnv. if called as wrapper(0), fifu is defined only locally and nls (actually, nlsModel, I think) does not know what I'm talking about. I understand, the problem is that the scoping rules are such that nls does not resolve 'fifu' in the parent environment, but rather in the GlobalEnv. (this is different for the data, which *are* taken from the parent environment of the nls-call). I assume by `data' you mean not the `data' argument to nls but the variables referred to in your formula. I tried some variants of using eval but without starting to modify nls itself there seems no way (up to now, anyway). The solution to assign 'fifu' directly into the GlobalEnv does work, of course, but leads to the undesirable effect of accumulating objects in the workspace which are not needed there (and might overwrite existing ones). S has frame 1 for this purpose. The nearest equivalent I know in R is to attach an environment in position 2 and assign objects like 'fifu' there, which avoids your `undesirable effect'. in response to my first post, I got the hint that for lm the situation is different: it handles the above situation as desired (i.e. accepts local model definition). in so far one might even argue that this behaviour of lm and nls leads to an inconsistent behaviour of R in quite similar situations (e.g. replacing at some point a linar model by a nonlinear model in some large project is not achieved by simply replacing lm by nls somewhere deep down in the source code). I think that is simply wrong. It is a _function_ in your non-linear model definition that is not being found, not the variables (which you call `data' above). You do currently need to ensure that the functions in your formulae are in scope when called from nlsModel. Around R 1.2.x the notion was introduced that variables should be looked for in the environment of a formula. Functions using model.frame got converted to do that, but nls did not. I guess that the best way forward is to ensure that nls (and nlsModel) does search the environment of the formula for functions. -- Brian D. Ripley, [EMAIL PROTECTED] 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, UKFax: +44 1865 272595 __ [EMAIL PROTECTED] 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
Re: [R] nls and R scoping rules
On Thu, 10 Jun 2004, Prof Brian Ripley wrote: Around R 1.2.x the notion was introduced that variables should be looked for in the environment of a formula. Functions using model.frame got converted to do that, but nls did not. I guess that the best way forward is to ensure that nls (and nlsModel) does search the environment of the formula for functions. It transpires that is rather easy to achieve. At the top of nlsModel and nlsModel.plinear use env - new.env(parent=environment(form)) instead of env - new.env() This then automatically searches for objects used in the formula Notes 1) nls is in a namespace, so you need to fix the copy in the namespace or fix the source code and rebuild. 2) This will add to the baggage needed when you save() a nls fit in a workspace. I think that is inevitable as we cannot just identify the funtions used in the formula (as they might call other functions in the local environment), and it is necessary to capture the objects needed to evaluate the formula for the predict() method to be reliable. We could call all.names() to get the names of functions used directly in the formula, but that seems not good enough (previous para). Question to the cognescenti: is the price in 2) too great for this to be done for 1.9.1? I will put the change in R-devel for now. -- Brian D. Ripley, [EMAIL PROTECTED] 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, UKFax: +44 1865 272595 __ [EMAIL PROTECTED] 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
Re: [R] nls and R scoping rules
Prof Brian Ripley wrote: On Thu, 10 Jun 2004, Prof Brian Ripley wrote: Around R 1.2.x the notion was introduced that variables should be looked for in the environment of a formula. Functions using model.frame got converted to do that, but nls did not. I guess that the best way forward is to ensure that nls (and nlsModel) does search the environment of the formula for functions. It transpires that is rather easy to achieve. At the top of nlsModel and nlsModel.plinear use env - new.env(parent=environment(form)) instead of env - new.env() This then automatically searches for objects used in the formula Notes 1) nls is in a namespace, so you need to fix the copy in the namespace or fix the source code and rebuild. 2) This will add to the baggage needed when you save() a nls fit in a workspace. I think that is inevitable as we cannot just identify the funtions used in the formula (as they might call other functions in the local environment), and it is necessary to capture the objects needed to evaluate the formula for the predict() method to be reliable. We could call all.names() to get the names of functions used directly in the formula, but that seems not good enough (previous para). Question to the cognescenti: is the price in 2) too great for this to be done for 1.9.1? I will put the change in R-devel for now. thank's a lot for the two responses. that seems exactly what helps me out. remaining question: how can I edit (I mean from within R, not by messing around with the source code directly) an invisible function object such as nlsModel.plinear? help.search('invisible'), help('function'), help('edit') at least did not tell me. joerg __ [EMAIL PROTECTED] 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
Re: [R] nls and R scoping rules
On Thu, 10 Jun 2004, joerg van den hoff wrote: Prof Brian Ripley wrote: On Thu, 10 Jun 2004, Prof Brian Ripley wrote: Around R 1.2.x the notion was introduced that variables should be looked for in the environment of a formula. Functions using model.frame got converted to do that, but nls did not. I guess that the best way forward is to ensure that nls (and nlsModel) does search the environment of the formula for functions. It transpires that is rather easy to achieve. At the top of nlsModel and nlsModel.plinear use env - new.env(parent=environment(form)) instead of env - new.env() This then automatically searches for objects used in the formula Notes 1) nls is in a namespace, so you need to fix the copy in the namespace or fix the source code and rebuild. 2) This will add to the baggage needed when you save() a nls fit in a workspace. I think that is inevitable as we cannot just identify the funtions used in the formula (as they might call other functions in the local environment), and it is necessary to capture the objects needed to evaluate the formula for the predict() method to be reliable. We could call all.names() to get the names of functions used directly in the formula, but that seems not good enough (previous para). Question to the cognescenti: is the price in 2) too great for this to be done for 1.9.1? I will put the change in R-devel for now. thank's a lot for the two responses. that seems exactly what helps me out. remaining question: how can I edit (I mean from within R, not by messing around with the source code directly) an invisible function object such as nlsModel.plinear? help.search('invisible'), help('function'), help('edit') at least did not tell me. It depends why they are hidden, but for functions not exported from a namespace see ?fixInNamespace (hence my comment about namespaces). -- Brian D. Ripley, [EMAIL PROTECTED] 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, UKFax: +44 1865 272595 __ [EMAIL PROTECTED] 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
Re: [R] nls and R scoping rules
On Thu, 10 Jun 2004, Prof Brian Ripley wrote: On Thu, 10 Jun 2004, Prof Brian Ripley wrote: Around R 1.2.x the notion was introduced that variables should be looked for in the environment of a formula. Functions using model.frame got converted to do that, but nls did not. I guess that the best way forward is to ensure that nls (and nlsModel) does search the environment of the formula for functions. It transpires that is rather easy to achieve. At the top of nlsModel and nlsModel.plinear use env - new.env(parent=environment(form)) instead of env - new.env() This then automatically searches for objects used in the formula Notes 1) nls is in a namespace, so you need to fix the copy in the namespace or fix the source code and rebuild. 2) This will add to the baggage needed when you save() a nls fit in a workspace. I think that is inevitable as we cannot just identify the funtions used in the formula (as they might call other functions in the local environment), and it is necessary to capture the objects needed to evaluate the formula for the predict() method to be reliable. We could call all.names() to get the names of functions used directly in the formula, but that seems not good enough (previous para). Question to the cognescenti: is the price in 2) too great for this to be done for 1.9.1? I will put the change in R-devel for now. I don't think so. The fit objects already contain the formula (via the environment of the functions in the structure). Since environment sharing is preserved within a serialization, this means the change would only alter the parent of the env environment, not add anything extra. Best, luke -- Luke Tierney University of Iowa Phone: 319-335-3386 Department of Statistics andFax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: [EMAIL PROTECTED] Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu __ [EMAIL PROTECTED] 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] scoping rules
is there a good way to get the following fragment to work when calling it as wrapper(1) ? # cut here== wrapper - function (choose=0) { x - seq(0,2*pi,len=100) y - sin(1.5*x); y - rnorm(y,y,.1*max(y)) if (choose==0) { rm(fifu,pos=1) fifu - function(w,x) {sin(w*x)} } else assign('fifu',function(w,x) {sin(w*x)},.GlobalEnv) res - nls(y ~ fifu(w,x),start=list(w=1)) res } # cut here== I understand, the problem is that the scoping rules are such that nls does not resolve 'fifu' in the parent environment, but rather in the GlobalEnv. (this is different for the data, which *are* taken from the parent environment of the nls-call). The solution to assign 'fifu' directly into the GlobalEnv (which happens when calling 'wrapper(1)) does obviously work but leads to the undesirable effect of accumulating objects in the workspace which are not needed there (and might overwrite existing ones). so: is there a way to enforce that nls takes the model definition from the parent environment together with the data? joerg __ [EMAIL PROTECTED] 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
Re: [R] Scoping rules
On Wed, 8 Oct 2003, Roger D. Peng wrote: I think I misinterpreted this section of the help file for get(): If `inherits' is `FALSE', only the first frame of the specified environment is inspected. If `inherits' is `TRUE', the search is continued up through the parent frames until a bound value of the right mode is found. Should this read parent environments instead of parent frames? I'm taking this from R 1.7.1. It should read `enclosing' not `parent' for a start. Thanks: we will try to get this consistent. -roger Prof Brian Ripley wrote: On Wed, 8 Oct 2003, Roger D. Peng wrote: It seems like you want in fnB get(AA$first, envir = parent.frame(1)) but I'm entirely clear on why your original function doesn't work. My understanding was that get() should search through the parent frames. Where did you get that idea from? Argument `inherits' to get() defaults to TRUE and is defined as inherits: should the enclosing frames of the environment be inspected? Note `enclosing', not `parent'. So the normal R scope rules apply when looking for an object from the frame of fnB, which as its environment (aka enclosing frame) is the workspace (.GlobalEnv) is to look in the local frame and then along the search path. [This does seem a fairly common misconception, so if you do have any idea in which document it arises it would be good to know.] Peter Alspach wrote: Dear List members: I'm using R1.7.1 (Windows 2000) and having difficulty with scoping. I've studied the FAQ and on-line manuals and think I have identified the source of my difficulty, but cannot work out the solution. For the purposes of illustration. I have three functions as defined below: fnA - function(my.x) { list(first=as.character(substitute(my.x)), second=sqrt(my.x)) } fnB - function(AA) { tmp.x - get(AA$first) tmp.x^2 } fnC - function() { x - 1:2 y - fnA(x) z - fnB(y) c(x,y,z) } fnA() has a vector as an argument and returns the name of the vector and the square root of its elements in a list. fn(B) takes the result of fn(A) as its argument, gets the appropriate vector and computes the square of its elements. These work fine when called at the command line. fnC() defines a local vector x and calls fnA() which operates on this vector. Then fnB() is called, but it operates on a global vector x in GlobalEnv (or returns an error is x doesn't exist there) - but I want it to operate on the local vector. I am not sure what you really want to do here, but R works best if you pass functions an object to work on, and not the name of an object. Normally this sort of thing is best avoided, but if it is really needed it is normally simpler to find the object in the calling function (your fnC). I think this is related to the enclosing environment of all three functions being GlobalEnv (since they were created at the command line), but the parent environment of fnB() being different when invoked from within fnC(). My questions: 1 Have I correctly understood the issue ? 2 How do I make fnB() operate on the local vector rather than the global one ? 3 And, as an aside, I have used as.character(substitute(my.x)) to pass the name - but deparse(substitute(my.x)) also works. Is there any reason to prefer one over the other? deparse() is preferred. One subtle reason is what happens with very long expressions (and note deparse may give more than one line of output), but the main reason is what happens with expressions such as calls: fn1 - function(x) as.character(substitute(x)) fn2 - function(x) deparse(substitute(x)) fn1(log(x)) [1] log x fn2(log(x)) [1] log(x) It is normally dangerous to use get() on the result of deparse(substitute()), as the latter may be the character representation of an expression and not a simple name. -- Brian D. Ripley, [EMAIL PROTECTED] 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, UKFax: +44 1865 272595 __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
[R] Scoping Rules: Summary
Thanks to Andy Liaw, Roger Peng, Thomas Lumley, Brian Ripley and Peter Dalgaard, all of whom addressed my questions or threads arising from them. The full messages were posted to the list so this is a brief summary: Andy Liaw explained the difference between lexical and dynamic scoping and the rationale behind the choice of lexical scoping for R. Roger Peng showed how to modify fnB. Brian Ripley suggested that it is generally better to pass functions an object rather than just the name, and warned of the dangers of using get() on the result of deparse(substitute()). Thanks all Peter Alspach Original question below: I'm using R1.7.1 (Windows 2000) and having difficulty with scoping. I've studied the FAQ and on-line manuals and think I have identified the source of my difficulty, but cannot work out the solution. For the purposes of illustration. I have three functions as defined below: fnA - function(my.x) { list(first=as.character(substitute(my.x)), second=sqrt(my.x)) } fnB - function(AA) { tmp.x - get(AA$first) tmp.x^2 } fnC - function() { x - 1:2 y - fnA(x) z - fnB(y) c(x,y,z) } fnA() has a vector as an argument and returns the name of the vector and the square root of its elements in a list. fn(B) takes the result of fn(A) as its argument, gets the appropriate vector and computes the square of its elements. These work fine when called at the command line. fnC() defines a local vector x and calls fnA() which operates on this vector. Then fnB() is called, but it operates on a global vector x in GlobalEnv (or returns an error is x doesn't exist there) - but I want it to operate on the local vector. I think this is related to the enclosing environment of all three functions being GlobalEnv (since they were created at the command line), but the parent environment of fnB() being different when invoked from within fnC(). My questions: 1 Have I correctly understood the issue ? 2 How do I make fnB() operate on the local vector rather than the global one ? 3 And, as an aside, I have used as.character(substitute(my.x)) to pass the name - but deparse(substitute(my.x)) also works. Is there any reason to prefer one over the other? Thank you ... __ The contents of this e-mail are privileged and/or confidenti...{{dropped}} __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
[R] Scoping rules
Dear List members: I'm using R1.7.1 (Windows 2000) and having difficulty with scoping. I've studied the FAQ and on-line manuals and think I have identified the source of my difficulty, but cannot work out the solution. For the purposes of illustration. I have three functions as defined below: fnA - function(my.x) { list(first=as.character(substitute(my.x)), second=sqrt(my.x)) } fnB - function(AA) { tmp.x - get(AA$first) tmp.x^2 } fnC - function() { x - 1:2 y - fnA(x) z - fnB(y) c(x,y,z) } fnA() has a vector as an argument and returns the name of the vector and the square root of its elements in a list. fn(B) takes the result of fn(A) as its argument, gets the appropriate vector and computes the square of its elements. These work fine when called at the command line. fnC() defines a local vector x and calls fnA() which operates on this vector. Then fnB() is called, but it operates on a global vector x in GlobalEnv (or returns an error is x doesn't exist there) - but I want it to operate on the local vector. I think this is related to the enclosing environment of all three functions being GlobalEnv (since they were created at the command line), but the parent environment of fnB() being different when invoked from within fnC(). My questions: 1 Have I correctly understood the issue ? 2 How do I make fnB() operate on the local vector rather than the global one ? 3 And, as an aside, I have used as.character(substitute(my.x)) to pass the name - but deparse(substitute(my.x)) also works. Is there any reason to prefer one over the other? Thank you ... Peter Alspach __ The contents of this e-mail are privileged and/or confidential to the named recipient and are not to be used by any other person and/or organisation. If you have received this e-mail in error, please notify the sender and delete all material pertaining to this e-mail. __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
Re: [R] Scoping rules
It seems like you want in fnB get(AA$first, envir = parent.frame(1)) but I'm entirely clear on why your original function doesn't work. My understanding was that get() should search through the parent frames. -roger Peter Alspach wrote: Dear List members: I'm using R1.7.1 (Windows 2000) and having difficulty with scoping. I've studied the FAQ and on-line manuals and think I have identified the source of my difficulty, but cannot work out the solution. For the purposes of illustration. I have three functions as defined below: fnA - function(my.x) { list(first=as.character(substitute(my.x)), second=sqrt(my.x)) } fnB - function(AA) { tmp.x - get(AA$first) tmp.x^2 } fnC - function() { x - 1:2 y - fnA(x) z - fnB(y) c(x,y,z) } fnA() has a vector as an argument and returns the name of the vector and the square root of its elements in a list. fn(B) takes the result of fn(A) as its argument, gets the appropriate vector and computes the square of its elements. These work fine when called at the command line. fnC() defines a local vector x and calls fnA() which operates on this vector. Then fnB() is called, but it operates on a global vector x in GlobalEnv (or returns an error is x doesn't exist there) - but I want it to operate on the local vector. I think this is related to the enclosing environment of all three functions being GlobalEnv (since they were created at the command line), but the parent environment of fnB() being different when invoked from within fnC(). My questions: 1 Have I correctly understood the issue ? 2 How do I make fnB() operate on the local vector rather than the global one ? 3 And, as an aside, I have used as.character(substitute(my.x)) to pass the name - but deparse(substitute(my.x)) also works. Is there any reason to prefer one over the other? Thank you ... Peter Alspach __ The contents of this e-mail are privileged and/or confidential to the named recipient and are not to be used by any other person and/or organisation. If you have received this e-mail in error, please notify the sender and delete all material pertaining to this e-mail. __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
Re: [R] Scoping rules
On Wed, 8 Oct 2003, Roger D. Peng wrote: It seems like you want in fnB get(AA$first, envir = parent.frame(1)) but I'm entirely clear on why your original function doesn't work. My understanding was that get() should search through the parent frames. No, get() searches through the enclosing frames, like ordinary variable lookup. The only way to get dynamic scope is to specify it explicitly -thomas -roger Peter Alspach wrote: Dear List members: I'm using R1.7.1 (Windows 2000) and having difficulty with scoping. I've studied the FAQ and on-line manuals and think I have identified the source of my difficulty, but cannot work out the solution. For the purposes of illustration. I have three functions as defined below: fnA - function(my.x) { list(first=as.character(substitute(my.x)), second=sqrt(my.x)) } fnB - function(AA) { tmp.x - get(AA$first) tmp.x^2 } fnC - function() { x - 1:2 y - fnA(x) z - fnB(y) c(x,y,z) } fnA() has a vector as an argument and returns the name of the vector and the square root of its elements in a list. fn(B) takes the result of fn(A) as its argument, gets the appropriate vector and computes the square of its elements. These work fine when called at the command line. fnC() defines a local vector x and calls fnA() which operates on this vector. Then fnB() is called, but it operates on a global vector x in GlobalEnv (or returns an error is x doesn't exist there) - but I want it to operate on the local vector. I think this is related to the enclosing environment of all three functions being GlobalEnv (since they were created at the command line), but the parent environment of fnB() being different when invoked from within fnC(). My questions: 1 Have I correctly understood the issue ? 2 How do I make fnB() operate on the local vector rather than the global one ? 3 And, as an aside, I have used as.character(substitute(my.x)) to pass the name - but deparse(substitute(my.x)) also works. Is there any reason to prefer one over the other? Thank you ... Peter Alspach __ The contents of this e-mail are privileged and/or confidential to the named recipient and are not to be used by any other person and/or organisation. If you have received this e-mail in error, please notify the sender and delete all material pertaining to this e-mail. __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help Thomas Lumley Assoc. Professor, Biostatistics [EMAIL PROTECTED] University of Washington, Seattle __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
Re: [R] Scoping rules
On Wed, 8 Oct 2003, Roger D. Peng wrote: It seems like you want in fnB get(AA$first, envir = parent.frame(1)) but I'm entirely clear on why your original function doesn't work. My understanding was that get() should search through the parent frames. Where did you get that idea from? Argument `inherits' to get() defaults to TRUE and is defined as inherits: should the enclosing frames of the environment be inspected? Note `enclosing', not `parent'. So the normal R scope rules apply when looking for an object from the frame of fnB, which as its environment (aka enclosing frame) is the workspace (.GlobalEnv) is to look in the local frame and then along the search path. [This does seem a fairly common misconception, so if you do have any idea in which document it arises it would be good to know.] Peter Alspach wrote: Dear List members: I'm using R1.7.1 (Windows 2000) and having difficulty with scoping. I've studied the FAQ and on-line manuals and think I have identified the source of my difficulty, but cannot work out the solution. For the purposes of illustration. I have three functions as defined below: fnA - function(my.x) { list(first=as.character(substitute(my.x)), second=sqrt(my.x)) } fnB - function(AA) { tmp.x - get(AA$first) tmp.x^2 } fnC - function() { x - 1:2 y - fnA(x) z - fnB(y) c(x,y,z) } fnA() has a vector as an argument and returns the name of the vector and the square root of its elements in a list. fn(B) takes the result of fn(A) as its argument, gets the appropriate vector and computes the square of its elements. These work fine when called at the command line. fnC() defines a local vector x and calls fnA() which operates on this vector. Then fnB() is called, but it operates on a global vector x in GlobalEnv (or returns an error is x doesn't exist there) - but I want it to operate on the local vector. I am not sure what you really want to do here, but R works best if you pass functions an object to work on, and not the name of an object. Normally this sort of thing is best avoided, but if it is really needed it is normally simpler to find the object in the calling function (your fnC). I think this is related to the enclosing environment of all three functions being GlobalEnv (since they were created at the command line), but the parent environment of fnB() being different when invoked from within fnC(). My questions: 1 Have I correctly understood the issue ? 2 How do I make fnB() operate on the local vector rather than the global one ? 3 And, as an aside, I have used as.character(substitute(my.x)) to pass the name - but deparse(substitute(my.x)) also works. Is there any reason to prefer one over the other? deparse() is preferred. One subtle reason is what happens with very long expressions (and note deparse may give more than one line of output), but the main reason is what happens with expressions such as calls: fn1 - function(x) as.character(substitute(x)) fn2 - function(x) deparse(substitute(x)) fn1(log(x)) [1] log x fn2(log(x)) [1] log(x) It is normally dangerous to use get() on the result of deparse(substitute()), as the latter may be the character representation of an expression and not a simple name. -- Brian D. Ripley, [EMAIL PROTECTED] 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, UKFax: +44 1865 272595 __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
Re: [R] Scoping rules
I think I misinterpreted this section of the help file for get(): If `inherits' is `FALSE', only the first frame of the specified environment is inspected. If `inherits' is `TRUE', the search is continued up through the parent frames until a bound value of the right mode is found. Should this read parent environments instead of parent frames? I'm taking this from R 1.7.1. -roger Prof Brian Ripley wrote: On Wed, 8 Oct 2003, Roger D. Peng wrote: It seems like you want in fnB get(AA$first, envir = parent.frame(1)) but I'm entirely clear on why your original function doesn't work. My understanding was that get() should search through the parent frames. Where did you get that idea from? Argument `inherits' to get() defaults to TRUE and is defined as inherits: should the enclosing frames of the environment be inspected? Note `enclosing', not `parent'. So the normal R scope rules apply when looking for an object from the frame of fnB, which as its environment (aka enclosing frame) is the workspace (.GlobalEnv) is to look in the local frame and then along the search path. [This does seem a fairly common misconception, so if you do have any idea in which document it arises it would be good to know.] Peter Alspach wrote: Dear List members: I'm using R1.7.1 (Windows 2000) and having difficulty with scoping. I've studied the FAQ and on-line manuals and think I have identified the source of my difficulty, but cannot work out the solution. For the purposes of illustration. I have three functions as defined below: fnA - function(my.x) { list(first=as.character(substitute(my.x)), second=sqrt(my.x)) } fnB - function(AA) { tmp.x - get(AA$first) tmp.x^2 } fnC - function() { x - 1:2 y - fnA(x) z - fnB(y) c(x,y,z) } fnA() has a vector as an argument and returns the name of the vector and the square root of its elements in a list. fn(B) takes the result of fn(A) as its argument, gets the appropriate vector and computes the square of its elements. These work fine when called at the command line. fnC() defines a local vector x and calls fnA() which operates on this vector. Then fnB() is called, but it operates on a global vector x in GlobalEnv (or returns an error is x doesn't exist there) - but I want it to operate on the local vector. I am not sure what you really want to do here, but R works best if you pass functions an object to work on, and not the name of an object. Normally this sort of thing is best avoided, but if it is really needed it is normally simpler to find the object in the calling function (your fnC). I think this is related to the enclosing environment of all three functions being GlobalEnv (since they were created at the command line), but the parent environment of fnB() being different when invoked from within fnC(). My questions: 1 Have I correctly understood the issue ? 2 How do I make fnB() operate on the local vector rather than the global one ? 3 And, as an aside, I have used as.character(substitute(my.x)) to pass the name - but deparse(substitute(my.x)) also works. Is there any reason to prefer one over the other? deparse() is preferred. One subtle reason is what happens with very long expressions (and note deparse may give more than one line of output), but the main reason is what happens with expressions such as calls: fn1 - function(x) as.character(substitute(x)) fn2 - function(x) deparse(substitute(x)) fn1(log(x)) [1] log x fn2(log(x)) [1] log(x) It is normally dangerous to use get() on the result of deparse(substitute()), as the latter may be the character representation of an expression and not a simple name. __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
Re: [R] scoping rules; summary
Robin Hankin wrote: Hi everyone thanks for the replies. The issue was NOT a font problem; I deliberately chose ll1 and l11 as examples of easily confused variable names (evidently these were too easily confused ;-). The code snippet was written as intended, and increment() contained a deliberate, highlighted, bug. I was asking for guidance on avoiding/finding this sort of coding error. That was why I wrote #bug here in the original code, and why the function was called increment()---because the function should have incremented x by adding a variable whose value was 1 (of course, the function as written, contrary to the desired functionality of increment(), added a variable whose value was 2). I guess I wasn't explicit enough here. Sorry. The fundamental problem was, how to tell that a variable being used in a function is not local? One answer (thanks Patrick!): conflicts() shows masked objects on the search path, which is not quite what I need: I want some way to list all non-local variables that increment() uses in its body. [The original variable names referred to genetic bandsharing data for possums, eg coates.female.pouchyoung.allbands.method5 and huapai.young.male.sibling.relatedness.method3 and huapai.old.female.nonsibling.relatedness.justdarkbands.method1 ad nauseum...hence the need for shorter example variable names!] ll1 - 2 #sic increment - function(x) { l11 - 1#sic return(x+ll1) #sic; deliberate bug here (sic) } I think you are looking for ls() together with the debugging tool browser(): increment - function(x){ l11 - 1 browser()# just for debugging return(x+ll1) } increment(1) # Now the browser opens and you can look for objects in the current enviroment with ls(). Uwe Ligges -- Robin Hankin, Lecturer, School of Geography and Environmental Science Tamaki Campus Private Bag 92019 Auckland New Zealand [EMAIL PROTECTED] tel 0064-9-373-7599 x6820; FAX 0064-9-373-7042 __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
[R] scoping rules; summary
Hi everyone thanks for the replies. The issue was NOT a font problem; I deliberately chose ll1 and l11 as examples of easily confused variable names (evidently these were too easily confused ;-). The code snippet was written as intended, and increment() contained a deliberate, highlighted, bug. I was asking for guidance on avoiding/finding this sort of coding error. That was why I wrote #bug here in the original code, and why the function was called increment()---because the function should have incremented x by adding a variable whose value was 1 (of course, the function as written, contrary to the desired functionality of increment(), added a variable whose value was 2). I guess I wasn't explicit enough here. Sorry. The fundamental problem was, how to tell that a variable being used in a function is not local? One answer (thanks Patrick!): conflicts() shows masked objects on the search path, which is not quite what I need: I want some way to list all non-local variables that increment() uses in its body. [The original variable names referred to genetic bandsharing data for possums, eg coates.female.pouchyoung.allbands.method5 and huapai.young.male.sibling.relatedness.method3 and huapai.old.female.nonsibling.relatedness.justdarkbands.method1 ad nauseum...hence the need for shorter example variable names!] ll1 - 2 #sic increment - function(x) { l11 - 1#sic return(x+ll1) #sic; deliberate bug here (sic) } -- Robin Hankin, Lecturer, School of Geography and Environmental Science Tamaki Campus Private Bag 92019 Auckland New Zealand [EMAIL PROTECTED] tel 0064-9-373-7599 x6820; FAX 0064-9-373-7042 __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
[R] scoping rules
Hi I recently found a bug that was isomorphic to the following: ll1 - 2 increment - function(x) { l11 - 1 return(x+ll1) #bug here } Of course, R is obeying the scoping rules just fine, but I'm evidently not setting the do.what.I.mean.not.what.I.say variable correctly. Now, how do I avoid making this type of error? ... and what is the best tool for tracking it down? -- Robin Hankin, Lecturer, School of Geography and Environmental Science Tamaki Campus Private Bag 92019 Auckland New Zealand [EMAIL PROTECTED] tel 0064-9-373-7599 x6820; FAX 0064-9-373-7042 __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
Re: [R] scoping rules
On Sunday 16 March 2003 09:16 pm, Robin Hankin wrote: Hi I recently found a bug that was isomorphic to the following: ll1 - 2 increment - function(x) { l11 - 1 You are not really using this variable (l11, not ll1) anywhere. Is that a typo? What exactly do you want to happen ? return(x+ll1) #bug here } Of course, R is obeying the scoping rules just fine, but I'm evidently not setting the do.what.I.mean.not.what.I.say variable correctly. Now, how do I avoid making this type of error? ... and what is the best tool for tracking it down? __ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help