I've quickly became an addict to quosures, and I'm refactoring all the code in my EDAs so that it works with datasets having different headers. I found two difficulties:
- when testing assertions (e.g., in the code below, testing that the variable corresponding to a quosure
enquo(factor_var)
is a factor), code of the formstopifnot(is.factor(dataframe[[!! factor_var]))
doesn't work, nor does code of the formstopifnot(is.factor(select(dataframe, !! factor_var)))
. As you can see below, I had to usequo_name
. - How to get
mutate
to work when the quosure is on the left hand side of themutate
assignment? Again, herequo_name
+!!
+:=
seems the only way. Not very readable...but at least, once committed to memory, very easy to reapply every time is needed.
Here is my code: the test_function
must check if factor_var
is a factor, or abort. If it's a factor, then it mutate
s all the NA
to extra factor levels using forcats::fct_explicit_na()
.
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(rlang)
library(forcats)
test_function <- function(dataframe, factor_var){
factor_var <- enquo(factor_var)
factor_var_name <- quo_name(factor_var)
stopifnot(is.factor(dataframe[[factor_var_name]]))
dataframe <- dataframe %>%
mutate(!! factor_var_name := forcats::fct_explicit_na(!! factor_var))
return(dataframe)
}
my_iris <- iris
n <- nrow(my_iris)
index <- sample(seq_len(n),10)
my_iris$Species[index] <- NA
my_iris <- test_function(my_iris, Species)
Created on 2018-09-11 by the reprex package (v0.2.0).
Question: by introducing quo_name
in the stopifnot
and mutate
assignment, did I do the right thing? Or are there simpler solutions?