这似乎是一个过于复杂的问题,但它让我有些发疯了一段时间。也是出于好奇,因为我已经有了做我需要的方法,所以没那么重要。
在 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
作为选项)。
如果有人碰巧比我更了解环境,特别是在这种“奇怪”的情况下,我很想知道如何解决这个问题。
谢谢你的时间,
胡安