【发布时间】:2018-07-19 17:03:45
【问题描述】:
函数base::substitute(expr, env),根据其文档页面,
返回(未计算的)表达式 expr 的解析树,替换 env 中绑定的任何变量。
我正在寻找一种方法来替换不是在一个特定环境中而是在当前调用堆栈中的所有环境中绑定的任何变量,即通过迭代 parent.frame(i) 而遇到的所有环境i 在 @ 987654324@。此外,我希望应用标准范围规则。
这是一个矛盾:R 中的标准作用域是词法的,但我在这里描述的是动态作用域(感谢 @MikkoMarttila 帮助我澄清这一点)。我真正想要的是一种替换任何变量的方法,这些变量不是绑定在一个特定环境中,而是在所有父封闭环境中,可以通过重复应用base::parent.env() 来枚举这些变量的集合。
考虑以下示例:
do_something <- function(todo) {
cat(
paste(
deparse(substitute(todo, environment())),
collapse = "\n"
)
)
}
nested_do <- function() {
var_2 <- "goodbye"
do_something({
print(var_1)
print("world")
print(var_2)
})
}
var_1 <- "hello"
nested_do()
目前这给了
print(var_1)
print("world")
print(var_2)
我想去哪里
print("hello")
print("world")
print("goodbye")
我查看了base::bquote() 和rlang::enexpr(),但是对于这两个变量,我必须使用.() 或!! 明确标记要替换/取消引用的变量。我宁愿不必手动指定变量,而是解决找到的所有问题(就像在base::substitute() 中一样)。此外,我尝试使用各自的env 参数迭代地应用base::substitute(),并查看了oshka::expand(),但我没有尝试过任何我需要的东西。
非常感谢任何帮助。
附加上下文
我正在努力实现以下目标:我正在开发一个运行 LSF 的集群。这意味着我可以使用提交工具bsub 提交作业,该工具可以将 R 文件作为输入。现在我想要一个生成这些输入文件的脚本(例如,使用函数do_something())。
long_running_fun <- function(x) {
Sys.sleep(100)
x / 2
}
var_1 <- 2 + 2
var_2 <- var_1 + 10
do_something({
print(var_1)
var_3 <- long_running_fun(var_2)
print(var_3)
})
在上述情况下,我希望将以下(或等效的)写入文件
print(4)
var_3 <- long_running_fun(14)
print(var_3)
【问题讨论】:
-
只是为了澄清标题编辑:我认为“父环境”命名在这里有点误导,因为(据我所知)执行环境的父级是封闭环境,这通常是不同的来自调用环境。
-
也许我理解错了,但在我看来,附加上下文中所需的输出与原始问题有些矛盾?本来你想替换,但是这里你只想捕获表达式?
-
我很抱歉。我漫不经心地复制粘贴了所需的输出。现在应该更正了。
-
所以基本上,你有一个代码 sn-p 你想作为工作提交;但是该代码 sn-p 取决于当前上下文,并且您无法将上下文传递给运行 sn-p 的集群? (这对吗?)所以您需要替换当前上下文所需的所有信息?
-
是的,听起来差不多。
标签: r scope substitution rlang nse