20.10 Using tidy evaluation
Most of the time we might not call it directly, but call a function that uses eval_tidy()
(becoming developer AND user)
Use case: resample and subset
We have a function that resamples a dataset:
resample(sample_df, 10)
#> a b c
#> 4 4 2 4
#> 3 3 3 2
#> 2 2 4 3
#> 3.1 3 3 2
#> 1 1 5 5
#> 5 5 1 1
#> 1.1 1 5 5
#> 5.1 5 1 1
#> 3.2 3 3 2
#> 5.2 5 1 1
But we also want to use subset and we want to create a function that allow us to resample and subset (with subset2()
) in a single step.
First attempt:
subsample(sample_df, b == c, 10)
#> Warning in b == c: longer object length is not a multiple of shorter object
#> length
#> Error in eval_tidy(rows, data): 'list' object cannot be coerced to type 'integer'
What happened?
subsample()
doesn’t quote any arguments and cond
is evaluated normally
So we have to quote cond
and unquote it when we pass it to subset2()
subsample <- function(df, cond, n = nrow(df)) {
cond <- enquo(cond)
df <- subset2(df, !!cond)
resample(df, n)
}
subsample(sample_df, b == c, 10)
#> a b c
#> 5 5 1 1
#> 1 1 5 5
#> 1.1 1 5 5
#> 5.1 5 1 1
#> 5.2 5 1 1
#> 1.2 1 5 5
#> 1.3 1 5 5
#> 5.3 5 1 1
#> 5.4 5 1 1
#> 5.5 5 1 1
Be careful!, potential ambiguity:
What would happen if x
exists in the calling environment but doesn’t exist in df
? Or if val
also exists in df
?
So, as developers of threshold_x()
and users of subset2()
, we have to add some pronouns:
Just remember:
As a general rule of thumb, as a function author it’s your responsibility to avoid ambiguity with any expressions that you create; it’s the user’s responsibility to avoid ambiguity in expressions that they create.