eval_tidy 中访问错误变量的函数
functions accessing wrong variables in eval_tidy
所以我一辈子都无法理解这里发生了什么。这本来应该是对可能的边缘情况的小探索,但它最终揭示了我对 R/tidy 评估的了解有多么少。
我想了解为什么当一个函数被编码为访问一个它没有在其参数中定义的变量时,eval_tidy
似乎无法掩盖它使用的变量。
考虑以下内容,其中 f
访问名为 sup
的变量,该变量未作为参数传入
library(rlang) # I'm using rlang 0.3.0
# Define `sup` globally
sup <- "yes"
f <- function() {
# Access whatever the `sup` variable is
if (sup == "yes") "YES"
else "NO"
}
f()
# 'YES'
q <- quote(f())
eval_tidy(q, c(sup="no"))
# 'YES'
我几乎尝试了所有方法,但我似乎无法从 f()
中屏蔽 sup
。
数据屏蔽对表达式进行操作,在您的示例中为 quote(f())
。然而,掩蔽是词汇的,而不是动态的。这意味着从表达式调用的函数将无法看到屏蔽的绑定。
有一种方法可以实现你想要的。您可以在继承自函数原始环境的环境中添加屏蔽绑定,并将后者替换为前者。 rlang 使这变得相当简单:
library("rlang")
sup <- "yes"
f <- function() if (sup == "yes") "YES" else "NO"
mask <- env(get_env(f), sup = "no")
f <- set_env(f, mask)
f()
#> [1] "NO"
然而,这似乎是一个相当奇怪的设计选择,可能会给您的 UI/DSL 一种奇怪的感觉。
所以我一辈子都无法理解这里发生了什么。这本来应该是对可能的边缘情况的小探索,但它最终揭示了我对 R/tidy 评估的了解有多么少。
我想了解为什么当一个函数被编码为访问一个它没有在其参数中定义的变量时,eval_tidy
似乎无法掩盖它使用的变量。
考虑以下内容,其中 f
访问名为 sup
的变量,该变量未作为参数传入
library(rlang) # I'm using rlang 0.3.0
# Define `sup` globally
sup <- "yes"
f <- function() {
# Access whatever the `sup` variable is
if (sup == "yes") "YES"
else "NO"
}
f()
# 'YES'
q <- quote(f())
eval_tidy(q, c(sup="no"))
# 'YES'
我几乎尝试了所有方法,但我似乎无法从 f()
中屏蔽 sup
。
数据屏蔽对表达式进行操作,在您的示例中为 quote(f())
。然而,掩蔽是词汇的,而不是动态的。这意味着从表达式调用的函数将无法看到屏蔽的绑定。
有一种方法可以实现你想要的。您可以在继承自函数原始环境的环境中添加屏蔽绑定,并将后者替换为前者。 rlang 使这变得相当简单:
library("rlang")
sup <- "yes"
f <- function() if (sup == "yes") "YES" else "NO"
mask <- env(get_env(f), sup = "no")
f <- set_env(f, mask)
f()
#> [1] "NO"
然而,这似乎是一个相当奇怪的设计选择,可能会给您的 UI/DSL 一种奇怪的感觉。