Skip to content

Problems accessing environment() in function

6 messages · Heiko Neuhaus, Uwe Ligges, Duncan Murdoch

#
Hi all,

I am trying to create a list of all variable/value combinations in 
environment().

When a function with unset arguments is called, the method I have been 
using fails with a "missing argument" error. However it should be 
possible to simply skip these missing objects in the generation of the list?

Could anyone recommend me a better way (that does not use a slow 
for/eval-combination) to achieve the desired effect?

You can easily reproduce my problem using this code:

------------------------------

test1 <- function(a, b, c)
{
   x <- as.list(environment())
   print ("hi from test1!")
   test2(a = a, b = b, c = c)
}

test2 <- function(a, b, c)
{
   # PROBLEM: Why can't I get a list as in test1() here?
   x <- as.list(environment())
   print ("hi from test2!")
}

test1()

------------------------------

I want my list "x" in test2() to work behave just like "x" in test1(). 
(In this example the correct list in test2() would be empty).

Thanks a lot for your time.

Best wishes,
Heiko Neuhaus
#
On 01.05.2012 19:57, Heiko Neuhaus wrote:
You are rying to pass a, b, c here and hence R tries to insert those 
into the environment of test2 once it is called, you have not passed 
arguments to your test1 call.

Uwe Ligges
#
Thanks a lot for your answer!
I am aware that I am passing non existing arguments here, which is why 
my method of creating a list of the environment "as.list(environment())" 
seems to fail in this case.

What I need is a way to just skip non existing objects when I create my 
list. In my given example I was intending to receive an empty list, 
since no valid arguments were passed to test2().

In other words: I want a list containing all _existing_ variable/value 
combinations and just skip the missing ones.

Thanks again for your time

Best wishes,
Heiko Neuhaus
#
On 02/05/2012 12:59 PM, Heiko Neuhaus wrote:
That's hard to do, because missing arguments exist, they just have a 
special value to signal that they were missing.  The missing() function 
tests for that value, but it is picky about its arguments.  So if you 
want to do all of this in R you probably need some tricky programming, 
like this:

f <- function(a,b,c) {
   names <- ls(environment())  # get all the names
   result <- list()
   for (n in names) {
     if (!do.call(missing, list(as.name(n))))
       result[n] <- get(n)
   }
   result
}

If you put the ls() call later, you'll pick up other local variables 
(names, result, n) as well.

Duncan Murdoch
#
Thank you very much for your suggestion.
I have already figured out a very similar solution using for/eval that 
basically does the same. I was hoping that I would somehow could get 
around the ugly loop using a more elegant approach. The loop should have 
a negative impact on performance since my function is using a lot of 
parameters. I was hoping, that there was some flag to tell the as.list 
function to ignore non existing objects. If that is not possible I will 
have to accept this.
Of course. That is why I call it at the very first line of my function.

Thanks again!

Heiko Neuhaus
#
On 12-05-02 5:20 PM, Heiko Neuhaus wrote:
What you're doing looks ugly, so don't expect an elegant solution.  (I 
say it's ugly because you're redefining terms like "exists".)  If you 
work with the language things will look nicer.

Duncan Murdoch

  The loop should have