Skip to content

sys.frame() and variables from parent frame

7 messages · José Miguel Delgado, David Winsemius, Zé Miguel +1 more

#
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
     }

metaCall()
#
On Feb 26, 2013, at 2:40 AM, Jos? Miguel Delgado wrote:

            
That doesn't make much sense.
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
#
On Feb 27, 2013, at 1:11 AM, Z? Miguel wrote:

            
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
#
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:
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

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

            
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.