I think this question must have been asked a bajillion times but it's not especially easy to search for so I'm asking it (probably) again.
Can someone help me understand the difference between {{}}
and !!
or !!sym(thing)
?
My primary interest is in taking column names (usually as strings) in variables, and passing them to various tidyverse/dplyr functions. Consider the following examples. Why does {{column_name}}
sometimes do what I want it to and sometimes not? Under what circumstances should I use !!sym(column_name)
instead? (or should I just use that every time?)
And of course, if this has been answered elsewhere, I'm happy to look there, but I haven't found anything that explains this clearly.
Thanks!
library(tidyverse)
column_name <- "cut"
wanted_cuts <- c("Ideal","Premium")
# this does what I want it to
diamonds %>%
select({{column_name}})
#> # A tibble: 53,940 × 1
#> cut
#> <ord>
#> 1 Ideal
#> 2 Premium
#> 3 Good
#> 4 Premium
#> 5 Good
#> 6 Very Good
#> 7 Very Good
#> 8 Very Good
#> 9 Fair
#> 10 Very Good
#> # … with 53,930 more rows
# this doesn't seem to work
diamonds %>%
filter({{column_name}} %in% wanted_cuts)
#> # A tibble: 0 × 10
#> # … with 10 variables: carat <dbl>, cut <ord>, color <ord>, clarity <ord>,
#> # depth <dbl>, table <dbl>, price <int>, x <dbl>, y <dbl>, z <dbl>
# neither does this
diamonds %>%
filter({{column_name}} == "Ideal")
#> # A tibble: 0 × 10
#> # … with 10 variables: carat <dbl>, cut <ord>, color <ord>, clarity <ord>,
#> # depth <dbl>, table <dbl>, price <int>, x <dbl>, y <dbl>, z <dbl>
# but this does work:
diamonds %>%
filter(!!sym(column_name) %in% wanted_cuts)
#> # A tibble: 35,342 × 10
#> carat cut color clarity depth table price x y z
#> <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
#> 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
#> 3 0.29 Premium I VS2 62.4 58 334 4.2 4.23 2.63
#> 4 0.23 Ideal J VS1 62.8 56 340 3.93 3.9 2.46
#> 5 0.22 Premium F SI1 60.4 61 342 3.88 3.84 2.33
#> 6 0.31 Ideal J SI2 62.2 54 344 4.35 4.37 2.71
#> 7 0.2 Premium E SI2 60.2 62 345 3.79 3.75 2.27
#> 8 0.32 Premium E I1 60.9 58 345 4.38 4.42 2.68
#> 9 0.3 Ideal I SI2 62 54 348 4.31 4.34 2.68
#> 10 0.24 Premium I VS1 62.5 57 355 3.97 3.94 2.47
#> # … with 35,332 more rows
column_name = "depth"
min_depth = 55
depths = c(61.5,62.8,60.4)
# this works
diamonds %>%
filter({{column_name}} > 55)
#> # A tibble: 53,940 × 10
#> carat cut color clarity depth table price x y z
#> <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
#> 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
#> 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
#> 4 0.29 Premium I VS2 62.4 58 334 4.2 4.23 2.63
#> 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
#> 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
#> 7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
#> 8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53
#> 9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49
#> 10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39
#> # … with 53,930 more rows
# and so does this
diamonds %>%
filter({{column_name}} > min_depth)
#> # A tibble: 53,940 × 10
#> carat cut color clarity depth table price x y z
#> <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
#> 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
#> 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
#> 4 0.29 Premium I VS2 62.4 58 334 4.2 4.23 2.63
#> 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
#> 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
#> 7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
#> 8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53
#> 9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49
#> 10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39
#> # … with 53,930 more rows
# but this doesn't
diamonds %>%
filter({{column_name}} %in% depths)
#> # A tibble: 0 × 10
#> # … with 10 variables: carat <dbl>, cut <ord>, color <ord>, clarity <ord>,
#> # depth <dbl>, table <dbl>, price <int>, x <dbl>, y <dbl>, z <dbl>
# and this does
diamonds %>%
filter(!!sym(column_name) %in% depths)
#> # A tibble: 3,579 × 10
#> carat cut color clarity depth table price x y z
#> <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
#> 2 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
#> 3 0.23 Ideal J VS1 62.8 56 340 3.93 3.9 2.46
#> 4 0.22 Premium F SI1 60.4 61 342 3.88 3.84 2.33
#> 5 0.23 Very Good G VVS2 60.4 58 354 3.97 4.01 2.41
#> 6 0.42 Premium I SI2 61.5 59 552 4.78 4.84 2.96
#> 7 0.24 Very Good D VVS1 61.5 60 553 3.97 4 2.45
#> 8 0.26 Very Good D VVS2 62.8 60 554 4.01 4.05 2.53
#> 9 0.8 Premium H SI1 61.5 58 2760 5.97 5.93 3.66
#> 10 0.73 Premium G VS1 61.5 58 2770 5.79 5.75 3.55
#> # … with 3,569 more rows
Created on 2022-10-25 by the reprex package (v2.0.1)