gpt4 book ai didi

r - 用于编写函数的rlang运算符的解释

转载 作者:行者123 更新时间:2023-12-04 03:30:41 25 4
gpt4 key购买 nike

我最近发布了两个与我尝试编写的函数相关的问题(12)。我收到了每个问题的有用答案,从而产生了以下两个功能:

second_table <- function(dat, variable1, variable2){
dat %>%
tabyl({{variable1}}, {{variable2}}, show_na = FALSE) %>%
adorn_percentages("row") %>%
adorn_pct_formatting(digits = 1) %>%
adorn_ns()

}

second_table2 = function(dat, variable1, variable2){
variable1 <- sym(variable1)

dat %>%
tabyl(!!variable1, {{variable2}}, show_na = FALSE) %>%
adorn_percentages("row") %>%
adorn_pct_formatting(digits = 1) %>%
adorn_ns()

}

这些功能按预期工作,但我以前从未使用过 rlang 包,并且仍然对 {{}} 运算符和 !! 之间的区别感到困惑。 + sym() 在查看可用文档并编写一些附加函数之后。我不喜欢使用我不完全理解的代码,并且相信我将来会进一步使用这些 rlang 运算符,因此非常感谢对这些运算符之间的区别进行通俗易懂的解释。

最佳答案

R 有一个称为非标准求值 (NSE) 的特殊功能,其中表达式按原样使用而不是被求值。大多数人在加载包时首先遇到 NSE:

a <- "rlang"

print(a) # Standard evaluation - the expression a is evaluated to its value
# [1] "rlang"

library(a) # Non-standard evaluation - the expression a is used as-is
# Error in library(a) : there is no package called ‘a’

rlang 通过提供三个主要函数来捕获未计算的符号和表达式来启用复杂的 NSE:

  • sym("x") 捕获符号(即变量名、列名等)。旧版本允许 sym(x),但我认为最新版本的 rlang 强制输入为字符串。

  • expr(a + b) 捕获任意表达式

  • quo(a + b) 捕获任意表达式和定义这些表达式的环境。

expressions 和 quosures 的区别在于,前者的求值是在直接环境中完成的,而后者总是在表达式所在的环境中求值被捕获:

f <- function(e) {a <- 2; b <- 3; eval_tidy(e)}
a <- 5; b <- 10

f(expr(a+b)) # Evaluated inside f
# [1] 5

f(quo(a+b)) # Evaluated in the environment where it is captured
# [1] 15

所有三个动词都有 en 等价物:ensymenexprenquo。这些用于捕获从函数内部提供给函数的符号和表达式。当您想要消除函数用户自己使用 sym 等的需要时,这很有用:

f <- function(x) {enexpr(x)}      # Expression captured within a function
f(a+b)

# This has exact equivalence to

f <- function(x) {x}
f(expr(a+b)) # The user has to do the capture themselves

在所有情况下,运算符 !! 都会计算符号和表达式。将其视为类固醇的 eval(),因为 !! 会强制立即求值,该求值优先于其他一切。除其他事项外,这对于迭代构建更复杂的表达式很有用:

a <- expr(b + 2)
expr(d * !!a) # a is evaluated immediately
# d * (b + 2)

expr(d * eval(a)) # evaluation of a is delayed
# d * eval(a)

综上所述,{{x}}!!enquo(x) 的简写符号>

关于r - 用于编写函数的rlang运算符的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66894311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com