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

Bert Gunter gunter.berton at gene.com
Wed Feb 27 19:16:51 CET 2013


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.

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



More information about the R-help mailing list