【发布时间】:2015-04-24 09:37:06
【问题描述】:
如果我声明一个函数,我可以引用之前的参数:
blah <- function( a=1, b=a ) { print(sprintf("a=%d, b=%d", a, b)) }
输出是:
> blah(10)
[1] "a=10, b=10"
> blah(10, b=30)
[1] "a=10, b=30"
但是,以下方法不起作用:
> blah(a=10, b=a)
Error in sprintf("a=%d, b=%d", a, b) : object 'a' not found
实际上,这或多或少是人们所期望的;那么为什么声明blah <- function(a=10, b=a) 有效呢?为什么这里的作用域与我调用函数时不同?
另外,为什么只有在调用sprintf 时才会出现错误?为什么调用函数时不立即抛出错误?我很困惑。
编辑:
在这里解释我的困惑。当我声明一个函数时,不会评估参数。 R 有惰性求值,变量在需要时进行求值。考虑一下:
> blah <- function( a=1, b=print("foo") ) { print( "So far, so good") ; print( b ) }
>
没有评价。我现在打电话给blah:
> blah()
[1] "So far, so good"
[1] "foo"
[1] "foo"
评估函数中的第一条语句,然后print("foo")。但是,那时, a 就在附近——我们在函数范围内拥有它。那么为什么不评估b=a 呢?当它发生时我们已经在函数中了,a 已经被声明了。
编辑 2:
在你跳到错误的结论之前,请注意,由于 R 的惰性求值,在 R 的函数声明中引用前面的参数是 perfectly fine。我不明白为什么它在函数声明中起作用,但在我调用时不起作用。我并不是说它应该或不应该起作用,只是想知道作用域的基本机制。
【问题讨论】:
-
您的环境中没有变量“a”。这就是您收到此错误的原因。例如,如果您首先定义
a = 150,它就可以工作。函数中的“a”和环境中的“a”是不同的对象。 -
那么为什么当我声明一个函数时它会起作用?
-
嗯,确实如此,你自己试试吧。
-
我不知道怎么做,这就是我问的原因。不过确实如此。此外,它是正确的语法。见johndcook.com/blog/2008/10/16/…
-
好的,误会请见谅。不过,当我用
blah <- function(a=10, b=a) { }声明我的函数时,a 不在我的环境中,是吗?如果是,它是何时以及如何创建的?