在 R 中提取函数参数值的奇怪行为

Strange behavior extracting function arguments values in R

如何提取列表中的所有函数参数值?

我试过这个:

x <- 1; y <- 2; z <- 3
testFunc <- function(a, b, c){
  args <- as.list(sys.call())[-1]
  evaluatedArgs <- lapply(args, function(x) eval(x))
  evaluatedArgs
}
str(testFunc(x,y,z))

List of 3
$ : symbol x
$ : num 2
$ : num 3

如您所见,如果 function(x) 内部的 x 和外部变量 x 存在奇怪的冲突,这会阻止对第一个参数的评估。

如何解决这个冲突?对我来说,这是一个奇怪的范围组合。

更新
现在我知道lapply(args, function(x) eval(x))解决了问题,但我想了解为什么会发生冲突。

您的 args 变量是 "symbol" 的 "list" 并在您的匿名 lapply 函数中作为参数传递。所以,隔离问题,你实际上是在做:

x = 10; y = 20
(function(x) eval(x))(substitute(x))
#x
(function(x) eval(x))(substitute(y))
#[1] 20

eval 在其 parent.frame 中评估其参数,这里是上述函数的 environment()。该环境包含函数的参数和传递的值:

(function(x) as.list(environment()))(substitute(x))
#$x
#x
#
(function(x) as.list(environment()))(substitute(y))
#$x
#y

在第一种情况下,eval 需要评估 参数 "x" 转换为评估 符号 "x"。要评估 符号 "x",它首先需要找到它,并且它在自己的环境中找到它,因为它是它的参数。找到的 "x" 包含 符号 "x" 并返回。在第二种情况下,评估 argument "x" 转换为评估不在其环境中的 symbol "y" ,但在其包含值“20”的父环境中找到并返回。

具体来说,我们需要将评估环境传递给 eval:

(function(x) { e = environment(); eval(x, parent.env(e)) })(substitute(x))
#[1] 10
(function(x) { e = environment(); eval(x, parent.env(e)) })(substitute(y))
#[1] 20

这里,参数被评估为函数当前环境的父环境(即 - 在这种情况下 - .GlobalEnv)。因此,修改您的函数以正确搜索:

x = 1; y = 2; z = 3
testFunc = function(a, b, c)
{
    args = as.list(sys.call())[-1]
    e = environment()
    lapply(args, function(x) eval(x, e))
}

我们得到:

str(testFunc(x,y,z))
#List of 3
# $ : num 1
# $ : num 2
# $ : num 3