R中这个函数的逻辑是什么?

Son*_*Lee 18 r function variable-assignment

我正在研究R函数中的参数,但是我有一些问题需要理解它的逻辑.

h <- function(a = 1, b = d){
    d <- (a + 1)^2
    c(a, b)
}

h()
# [1] 1 4
Run Code Online (Sandbox Code Playgroud)

我期望错误消息将返回,因为没有值b. d是在h函数下创建的,但是没有代码b = d可以b在函数中赋值h.

但结果是[1] 1 4.

如何b和d链接?

dig*_*All 20

默认函数参数值在R中进行延迟计算(即仅在需要时进行评估):

有关示例,请参阅此代码的输出:

printme <- function(name,x){cat('evaluating',name,'\n');x}

h <- function(a = printme('a',1), b = printme('b',d)){
  cat('computing d...\n')
  d <- (a + 1)^2
  cat('d computed\n')
  cat('concatenating a and b...\n')
  c(a, b)
  cat('a and b concatenated\n')
}

h()
Run Code Online (Sandbox Code Playgroud)

控制台输出:

computing d...
evaluating a 
d computed
concatenating a and b...
evaluating b 
a and b concatenated
Run Code Online (Sandbox Code Playgroud)

如您所见,d在计算默认值之前计算b

编辑:

此外,正如@BrodieG在注释中正确指出的那样,默认参数在函数环境中进行评估; 实际上,在上面的例子中,b可以初始化为d在函数环境中定义的变量的值.

相反,当您指定参数(不使用默认值)时,分配参数的表达式仍然会被延迟评估,但这次是在调用环境中,例如:

# same functions as above, but this time we specify the parameters in the call     
h(a=printme('a',123),b=printme('d',d))
Run Code Online (Sandbox Code Playgroud)

控制台输出:

computing d...
evaluating a 
d computed
concatenating a and b...
evaluating d 
Error in printme("d", d) : object 'd' not found
Run Code Online (Sandbox Code Playgroud)

请注意b评估参数时的错误,因为d在调用环境中找不到该错误.

  • 可能值得强调的是,默认参数是在它们所属的函数环境中计算的,而不是像非默认参数那样在调用环境中计算. (2认同)