[R] sys.frame() and variables from parent frame

David Winsemius dwinsemius at comcast.net
Wed Feb 27 19:30:01 CET 2013


On Feb 27, 2013, at 10:16 AM, Bert Gunter wrote:

> Some additional comments inline below to add to David's
> clarifications,  proffered largely in response to the poster's remark
> about coming to R from another language.
> 
> On Wed, Feb 27, 2013 at 9:44 AM, David Winsemius <dwinsemius at comcast.net> wrote:
>> 
>> On Feb 27, 2013, at 1:11 AM, Zé Miguel wrote:
>> 
>>> Dear David,
>>> 
>>> thanks for your reply. Sorry for the ambiguous example. I guess the get() will do it, but I still have a question regarding the parent frame. If I declare both function g and f in the global environment:
>>> 
>>> g <- function()
>>> {
>>> get(N,envir = ???)
>>> write(N)
>>> }
>>> 
>>> f<-function()
>>> {
>>> N<-99
>>> g()
>>> }
> 
> While David shows you below how you **can** do this, I would suggest
> that you **don't.**
> 
> The reason is that R largely follows a functional programming paradigm
> (e.g like Scheme or Lisp, for those in the know). Among other things,
> this means that essentially a function environment should be its own
> little world, and that anything needed for it to do its job in that
> world should be explicitly passed to it as a function argument. The
> practical danger of circumventing this paradigm and reaching back into
> a parent or global environment is that you don't know what will be
> there. Functions can be called by other functions and, if created to
> serve a purpose as an independent entity, might be called under
> circumstances entirely unforeseen by the function author.
> 
> There are certainly situations where one may wish to violate this
> dictum,  and I am sure R experts could provide compelling examples of
> them. But for the great mass of us unwashed, I think hewing to the R
> functional paradigm is a safer and more sensible course.

Oh, yes. I quite agree. I was taking that as an opportunity to illustrate why the N of 99 in inside his f() was NOT in the global environment (as it appeared that JMD expected). I was not suggesting that he try to shoehorn R into behaving like SAS or SPSS or BASIC. or Minitab or .... where everything is global.

-- 
David.


> 
> Cheers,
> Bert
> 
>>> 
>>> What is the environment I should be evoking in the get() function? Excuse me for the bad coding, I jst migrated from another language, please interpret it as a generic language.
>>> 
>> 
>> You can specify the global environment with either a function call or by a consant name
>> 
>> globalenv()
>> 
>> .GlobalEnv
>> 
>> 
>> In your code however, 'N' is not in the global environment and you are not passing a character argument to get() as you had been in your first example. Furthermore you have chosen to use write which does not gte the desired effect of reporting from inside a function.
>> 
>> g <- function()
>> {
>> get("N", envir = .GlobalEnv)  # character argument to get
>> cat(N)
>> }
>> 
>> f<-function()
>> {
>> N<-99  # not in the global environment
>> g()
>> }
>> 
>> N <- 42  # assigned in the global environment
>> f()
>> # returns 42
>> 
>> --
>> David.
>> 
>> 
>> 
>>> Cheers,
>>> 
>>> José
>>> 
>>> 
>>> 
>>> 
>>> On 27 February 2013 01:20, David Winsemius <dwinsemius at comcast.net> wrote:
>>> 
>>> On Feb 26, 2013, at 2:40 AM, José Miguel Delgado wrote:
>>> 
>>>> Dear R-help,
>>>> 
>>>> I wrote the following lines in order to use a variable from a parent frame in my callM() function. I would like to solve this by only editing the callM(function). When I run this code I obtain a empty list, meaning that eval(ls(),sys.frame(-1)) could not access the variables in the parent function. Any suggestions? Thanks in advance!
>>>> 
>>>> metaCall <- function()
>>>> {
>>>>   NN <- 99
>>>>   callM()
>>>>   }
>>>> 
>>>> callM <- function()
>>>> {
>>>>   Ls <- eval(ls(),sys.frame(-1))
>>>>   print(Ls)
>>>>   ### use Ls to call a certain model named M
>>> 
>>> That doesn't make much sense.
>>> 
>>>>   }
>>>> 
>>>> metaCall()
>>>> 
>>> 
>>> I don't think you need the eval() call:
>>> 
>>> metaCall <- function()
>>> {
>>>   NN <- 99
>>>   callM()
>>>   }
>>> 
>>> callM <- function()
>>> {
>>>   Ls <- ls(env=sys.frame(-1))
>>>   cat(Ls)
>>>   }
>>> 
>>> metaCall()
>>> NN
>>> 
>>> You should be aware that metaCall will not return anything since the last value is from the cat()-call or the print()-call and they each return NULL. If you wanted to go on from there and do something with 'NN", which is no longer a number but rather a character vector, you could, however.
>>> 
>>> Oh, I think I finally see .... the eval() was an attempt to retrieve  the object named "NN"" in the parent.frame? That means you need :
>>> 
>>> ?get
>>> 
>>> metaCall <- function()
>>> {
>>>   NN <- 99
>>>   callM()
>>>   }
>>> 
>>> callM <- function()
>>> {
>>>   Ls <- ls(env=sys.frame(-1))
>>>   str(get(Ls, env=sys.frame(-1)))
>>>   }
>>> 
>>> metaCall()
>>> # num 99
>>> 
>>> --
>>> David Winsemius
>>> Alameda, CA, USA
>>> 
>>> 
>>> 
>>> 
>>> --
>>> José Miguel Delgado
>>> Reichenberger Str. 52
>>> 10999 Berlin
>>> Tel. 0176 9633 92 56
>> 
>> David Winsemius
>> Alameda, CA, USA
>> 
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
> 
> 
> 
> -- 
> 
> Bert Gunter
> Genentech Nonclinical Biostatistics
> 
> Internal Contact Info:
> Phone: 467-7374
> Website:
> http://pharmadevelopment.roche.com/index/pdb/pdb-functional-groups/pdb-biostatistics/pdb-ncb-home.htm

David Winsemius
Alameda, CA, USA



More information about the R-help mailing list