this may seem like a overly complicated question, but it has me driving me a little nuts for some time. It is also for curiosity, because I already have a way of doing what I need, so is not that important.
In R, I need a function to return a named list object with all the arguments and the values entered by the user. For this I have made this code (toy example):
foo <- function(a=1, b=5, h='coconut') {
frm <- formals(foo)
parms <- frm
for (i in 1:length(frm))
parms[[i]] <- get(names(frm)[i])
return(parms)
}
So when this is asked:
> foo(b=0)
$a
[1] 1
$b
[1] 0
$h
[1] "coconut"
This result is perfect. The thing is, when I try to use lapply
to the same goal, so as to be a little more efficient (and elegant), it does not work as I want it to:
foo <- function(a=1, b=5, h='coconut') {
frm <- formals(foo)
parms <- lapply(names(frm), get)
names(parms) <- names(frm)
return(parms)
}
The problem clearly is with the environment in which get
evaluates it's first argument (a character string, the name of the variable). This I know in part from the error message:
> foo(b=0)
Error in FUN(c("a", "b", "h")[[1L]], ...) : object 'a' not found
and also, because when in the .GlobalEnv
environment there are objects with the right names, foo returns their values instead:
> a <- 100
> b <- -1
> h <- 'wallnut'
> foo(b=0)
$a
[1] 100
$b
[1] -1
$h
[1] "wallnut"
Obviously, as get
by default evaluates in the parent.frame()
, it searches for the objects in the .GlobalEnv
environment, instead of that of the current function. This is strange, since this does not happen with the first version of the function.
I have tried many options to make the function get
to evaluate in the right environment, but could not do it correctly (I've tried pos=-2,0,1,2
and envir=NULL
as options).
If anyone happen to know a little more than me about environments, specially in this "strange" cases, I would love to know how to solve this.
Thanks for your time,
Juan