参数默认值出现意外行为

时间:2011-12-08 02:19:50

标签: r

我只是遇到了一些奇怪的东西,希望有人可以在这里发表一些看法。基本上,当一个函数有一个参数,其默认值是参数的名称时,会发生奇怪的事情(好吧,对我来说很奇怪)。

例如:

y <- 5

f <- function(x=y) x^2

f2 <- function(y=y) y^2

我认为ff2是等价的;虽然它们在内部使用不同的变量名称,但它们都应该在全局环境中选择y对象以用作默认值。但是:

> f()
[1] 25

> f2()
Error in y^2 : 'y' is missing

不确定为什么会这样。

只是为了让事情变得更有趣:

f3 <- function(y=y) y$foo

> f3()
Error in f3() : 
  promise already under evaluation: recursive default argument reference or earlier problems?

我希望f3抛出一个错误,但不是那个!

这是在32位Windows XP SP3上的R 2.11.1,2.12.2和2.14上测试的。只加载标准包。

1 个答案:

答案 0 :(得分:1)

默认参数在函数范围内计算。您的f2与以下代码类似(几乎相同):

f2 = function(y) {
    if (missing(y)) y = y
    y^2
}

这使得范围更加清晰,并解释了为什么您的代码不起作用。

请注意,对于默认参数,此为true;显式传递的参数(当然)在调用者的范围内进行评估。

另一方面,懒惰评估与此无关:所有参数都被懒惰地评估,但调用f2(y)无需投诉。为了表明懒惰的评估总是发生,请考虑这一点:

f3 = function (x) {
    message("x has not been evaluated yet")
    x
}

f3(message("NOW x has been evaluated")

这将按此顺序打印:

x has not been evaluated yet
NOW x has been evaluated