Нестандартная оценка позволяет вам захватывать и манипулировать выражениями. В базе R это в основном достигается с помощью quote
:
quote(x)
# x
quote( a*log10(b+5) )
# a * log10(b + 5)
Однако любое захваченное выражение, состоящее из одного литерала, само по себе является литералом:
identical( quote(5), 5 ) # TRUE
identical( quote("a"), "a" ) # TRUE
identical( quote(FALSE), FALSE ) # TRUE
identical( quote(5+5), 10 ) # FALSE, expression is not a single literal
rlang::quo
от tidyverse основывается на этой функциональности путем захвата выражения И среды, в которой появилось это выражение. Вместе они определяют quosure :
quo(x)
# <quosure>
# expr: ^x
# env: global
f <- function() {quo(x)}
f()
# <quosure>
# expr: ^x
# env: 0x55b7e61d5c80
Хранение выражений рядом с их средами позволяет вам гарантировать, что они всегда оцениваются согласованным образом, пока они пробираются через ваш код:
x <- 5
g <- function( myexpr ) {
x <- 10
eval_tidy( myexpr )
}
x # Evaluate expression directly in its environment
# 5
g( quote(x) ) # Evaluate expression inside g()
# 10
g( quo(x) ) # Evaluate expression in its env, while inside g()
# 5
Однако при захвате литерала внутри фразы quo
назначает ему пустое окружение:
quo("x")
# <quosure>
# expr: ^"x"
# env: empty
Это потому, что строка "x"
всегда будет иметь значение "x"
, независимо от того, в какой среде она оценивается. Поэтому почти никогда не существует веской причины для quo
строкового объекта (или любого литерала для это важно). Он ничего не делает, и, как указано в комментариях, ваш код будет работать без него.