国家的文件do.call:
如果
quote是FALSE,默认值,则对参数求值(在调用环境中,而不是在 中envir)。
这句话向我暗示, when quote = FALSE,指定envir没有区别。然而,事实并非如此,事实上我遇到过需要指定envir才能使函数工作的情况。
最简单的可重现示例:
g1 <- function(x) {
args <- as.list(match.call())
args[[1]] <- NULL # remove the function call
do.call(print, args, quote = FALSE) # call print()
}
g2 <- function(x) {
args <- as.list(match.call())
args[[1]] <- NULL # remove the function call
do.call(print, args, quote = FALSE, envir = parent.frame()) # call print(), specifying envir
}
h1 <- function(x, y) {
g1(x*y)
}
h2 <- function(x, y) {
g2(x*y)
}
Run Code Online (Sandbox Code Playgroud)
使用这些函数,h2()行为就像人们想象的那样,但h1()不会:
h1(2, 3)
#Error in print(x) : object 'y' not found
h2(2, 3)
#[1] 6
y <- 100
h1(2, 3)
#[1] 600
## Looks like g1() took the value of y from the global environment
h2(2, 3)
#[1] 6
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释这里发生了什么吗?
注:有一个相关的帖子在这里,但我的阅读答案不具体说明什么do.call()用呢envir变量。
?do.call 说:
环境
评估呼叫的环境。如果 what 是字符串并且参数是符号或带引号的表达式,这将是最有用的。
如果 的what=参数do.call是一个字符串,我们可以很容易地说明这一点。然后envir=确定它在哪里查找。
e <- new.env()
e$f <- function() 2
f <- function() 3
do.call("f", list())
## [1] 3
do.call("f", list(), envir = e)
## [1] 2
Run Code Online (Sandbox Code Playgroud)
问题中的代码显示的参数也是如此。请注意,参数已被引用,因为match.call()正在使用。
是什么的情况下发生的h1,并g1是,这是有效的内部运行g1
do.call(print, list(call("*", quote(x), quote(y))), quote = FALSE)
Run Code Online (Sandbox Code Playgroud)
现在它找到xin g1(因为g1有一个参数x)但没有ying1所以它查找父环境,g1它的父环境是它找到的全局环境y。
在 和 的情况下h2,g2它在g2以下位置运行:
do.call(print, list(call("*", quote(x), quote(y))), quote = FALSE, envir = parent.frame())
Run Code Online (Sandbox Code Playgroud)
和它发现x和y在h2其的parentframe g2。
注意父环境和父框架不一样:
| 归档时间: |
|
| 查看次数: |
280 次 |
| 最近记录: |