x <- 1
plus_one <- function(x) {
x <- x + 1
x
}
plus_one(x)[1] 2
plus_one(x)[1] 2
tidyeval
R Workshop
Thursday, 13 February 2025
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 envirEducation <- "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
substitutereturns the parse tree for the (unevaluated) expression expr, substituting any variables bound in env.quotesimply 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 Fertilityrlang is providing the toolkit
rayshader by Brodie GaslamFertility as a promise, i.e. unknown in the Global Env)enquo()!!{{}}tidyevalAll you need to remember
Unquoted arguments in functions: use {{arg}}
:=
:= (walrus, from data.table)You learned to:
tidyevalI can categorically say if you’re pasting strings to program with dplyr, there is always better way.
Acknowledgments
Further reading
