我正在阅读Advanced R一书,对非标准评估一章中反复提到的“逃生舱”概念感到困惑。比如作者第一次提到这个词,它有如下定义:
作为开发人员,您应该始终提供一个逃生舱口:使用标准评估的函数的替代版本。
它也有一些关于逃生舱口的例子。其中一个示例来自Calling from another function部分。作者说:
通常,当函数被用户直接调用时,语言上的计算最有用,而当它们被其他函数调用时,用处不大。
请参见下面示例的代码:
sample_df <- data.frame(a = 1:5, b = 5:1, c = c(5, 3, 1, 4, 1))
subset2 <- function(x, condition) {
condition_call <- substitute(condition)
r <- eval(condition_call, x, parent.frame())
x[r, ]
}
scramble <- function(x) x[sample(nrow(x)), ]
subscramble <- function(x, condition) {
scramble(subset2(x, condition))
}
但它不起作用:
subscramble(sample_df, a >= 4)
# Error in eval(expr, envir, enclos) : object 'a' not found
traceback()
#> 5: eval(expr, envir, enclos)
#> 4: eval(condition_call, x, parent.frame()) at #3
#> 3: subset2(x, condition) at #1
#> 2: scramble(subset2(x, condition)) at #2
#> 1: subscramble(sample_df, a >= 4)
作者说我们可以编写一个版本的子集2(),在这种情况下采用已经引用的表达式。代码如下所示:
subset2_q <- function(x, condition) {
r <- eval(condition, x, parent.frame())
x[r, ]
}
subset2 <- function(x, condition) {
subset2_q(x, substitute(condition))
}
subscramble <- function(x, condition) {
condition <- substitute(condition)
scramble(subset2_q(x, condition))
}
然后它运行良好:
subscramble(sample_df, a >= 3)
#> a b c
#> 4 4 2 4
#> 5 5 1 1
#> 3 3 3 1
subscramble(sample_df, a >= 3)
#> a b c
#> 5 5 1 1
#> 3 3 3 1
#> 4 4 2 4
尽管作者给了我例子,但我仍然不明白逃生舱口。那么,有人可以在本书或 R 编程语言中解释它的定义吗?我的会话信息:
sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
Matrix products: default
locale:
[1] LC_COLLATE=Chinese (Simplified)_People's Republic of China.936
[2] LC_CTYPE=Chinese (Simplified)_People's Republic of China.936
[3] LC_MONETARY=Chinese (Simplified)_People's Republic of China.936
[4] LC_NUMERIC=C
[5] LC_TIME=Chinese (Simplified)_People's Republic of China.936
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.5.0 tools_3.5.0 yaml_2.2.0