【发布时间】:2011-12-22 10:20:51
【问题描述】:
这似乎是一个过于复杂的问题,但它让我有些发疯了一段时间。也是出于好奇,因为我已经有了做我需要的方法,所以没那么重要。
在 R 中,我需要一个函数来返回一个命名列表对象,其中包含用户输入的所有参数和值。为此,我制作了以下代码(玩具示例):
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)
}
所以当被问到时:
> foo(b=0)
$a
[1] 1
$b
[1] 0
$h
[1] "coconut"
这个结果是完美的。问题是,当我尝试使用 lapply 来实现相同的目标时,为了更高效(和优雅),它并没有像我想要的那样工作:
foo <- function(a=1, b=5, h='coconut') {
frm <- formals(foo)
parms <- lapply(names(frm), get)
names(parms) <- names(frm)
return(parms)
}
问题显然在于get 评估它的第一个参数(字符串,变量的名称)的环境。我部分地从错误消息中知道这一点:
> foo(b=0)
Error in FUN(c("a", "b", "h")[[1L]], ...) : object 'a' not found
而且,因为在 .GlobalEnv 环境中存在具有正确名称的对象时,foo 会返回它们的值:
> a <- 100
> b <- -1
> h <- 'wallnut'
> foo(b=0)
$a
[1] 100
$b
[1] -1
$h
[1] "wallnut"
显然,由于get 默认在parent.frame() 中求值,它在.GlobalEnv 环境中搜索对象,而不是在当前函数中搜索对象。这很奇怪,因为该函数的第一个版本不会发生这种情况。
我尝试了许多选项来使函数 get 在正确的环境中进行评估,但无法正确执行(我尝试了 pos=-2,0,1,2 和 envir=NULL 作为选项)。
如果有人碰巧比我更了解环境,特别是在这种“奇怪”的情况下,我很想知道如何解决这个问题。
感谢您的宝贵时间,
胡安
【问题讨论】: