<- 1
x <- function(x) {
plus_one <- x + 1
x
x
}plus_one(x)
[1] 2
plus_one(x)
[1] 2
tidyeval
Rworkshop
Friday, 9 February 2024
You will learn to:
The x
object in Global.Env wasn’t modified.
Does not mean adding quotes!
Also in higher level function
Like with
or subset
[1] 12 9 5 7 15 7 7 8 7 13 6 12 7 12 5 2 8 28 20 9 10 3 12 6 1
[26] 8 3 10 19 8 2 6 2 6 3 9 3 13 12 11 13 32 7 7 53 29 29
[1] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE TRUE
[13] FALSE TRUE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE TRUE FALSE
[25] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE
Standard evaluation of an expression
To evaluate an expression , you search environments for name bindings-values and perform the evaluation immediately.
Non-standard evaluation
Means you might
Why swiss
is found while being absent in Global_Env
?
[[1]] $ <env: global>
[[2]] $ <env: package:stats>
[[3]] $ <env: package:graphics>
[[4]] $ <env: package:grDevices>
[[5]] $ <env: package:utils>
[[6]] $ <env: package:datasets>
[[7]] $ <env: package:methods>
[[8]] $ <env: Autoloads>
[[9]] $ <env: tools:callr>
[[10]] $ <env: package:base>
swiss
lies in datasets
, so found after 5 fails
[[1]] $ <env: global>
[[2]] $ <env: package:forcats>
[[3]] $ <env: package:stats>
[[4]] $ <env: package:graphics>
[[5]] $ <env: package:grDevices>
[[6]] $ <env: package:utils>
[[7]] $ <env: package:datasets>
[[8]] $ <env: package:methods>
[[9]] $ <env: Autoloads>
[[10]] $ <env: tools:callr>
[[11]] $ <env: package:base>
The latest loaded package masks other namespaces
This is why dplyr::filter
masks stats::filter
when loading the tidyverse.
Education
is unknown in the Global EnvironmentQuoting prevents evaluation
But how to force evaluation then?
eval()
in data context with envir
Education <- "tic"
# the Education in the GlobalEnv won't clash
eval(expr = quote(Education), envir = swiss)
[1] 12 9 5 7 15 7 7 8 7 13 6 12 7 12 5 2 8 28 20 9 10 3 12 6 1
[26] 8 3 10 19 8 2 6 2 6 3 9 3 13 12 11 13 32 7 7 53 29 29
[1] 12 9 5 7 15 7 7 8 7 13 6 12 7 12 5 2 8 28 20 9 10 3 12 6 1
[26] 8 3 10 19 8 2 6 2 6 3 9 3 13 12 11 13 32 7 7 53 29 29
Education
is evaluated in the swiss
context only Fertility Agriculture Examination Education Catholic
V. De Geneve 35 1.2 37 53 42.34
Infant.Mortality
V. De Geneve 18
Works as expected!
Evaluation works by context even if an object name is colliding with the Global Environment!
But you better avoid names collisions for your own sanity!.
.data
and .env
pronouns exist if you need to precise who is where
Fertility Agriculture Examination Education Catholic
Lausanne 55.7 19.4 26 28 12.11
Neuchatel 64.4 17.6 35 32 16.92
V. De Geneve 35.0 1.2 37 53 42.34
Rive Droite 44.7 46.6 16 29 50.43
Rive Gauche 42.8 27.7 22 29 58.33
Infant.Mortality
Lausanne 20.2
Neuchatel 23.0
V. De Geneve 18.0
Rive Droite 18.2
Rive Gauche 19.3
substitute()
is neededquoted_filter_sub <- function(data, expr) {
q_expr <- substitute(expr)
# returns both the results and substituted expression
list(data[eval(q_expr, envir = data), 1:2],
q_expr
)
}
quoted_filter_sub(swiss, (Education + Examination) > 60)
[[1]]
Fertility Agriculture
Neuchatel 64.4 17.6
V. De Geneve 35.0 1.2
[[2]]
(Education + Examination) > 60
substitute
returns the parse tree for the (unevaluated) expression expr, substituting any variables bound in env.quote
simply returns its argument. The argument is not evaluated and can be any R expression.
tidyeval
?tidyeval
, i. e quasiquotation?When we need to unquote part of the expression: [!!]
rlang::qq_show()
helper to check
!!
dplyr
, unquote only Fertility
Tip
New in-depth blogpost on NSE with #rlang's quosures:https://t.co/yJQ81IdhYpJump down the rabbit hole with me to see how they work, and of course, how to implement them in base #rstats. pic.twitter.com/wo4GebqONt
— BrodieG (@BrodieGaslam) August 11, 2020
rlang
is providing the toolkit
rayshader
by Brodie GaslamFertility
as a promise, i.e. unknown in the Global Env)enquo()
!!
{{}}
tidyeval
All you need to remember
Unquoted arguments in functions: use {{arg}}
:=
:=
(walrus, from data.table
)You learned to:
tidyeval
I can categorically say if you’re pasting strings to program with dplyr, there is always better way.
Acknowledgments
Further reading