splicing a list which is an expression

I can pass a list to mutate by splicing it like in the below code:

library(tidyverse)
mtcars %>% 
  mutate(!!!list(a = 1,  b= 2)) %>% 
  head()
#>    mpg cyl disp  hp drat    wt  qsec vs am gear carb a b
#> 1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4 1 2
#> 2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4 1 2
#> 3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1 1 2
#> 4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1 1 2
#> 5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2 1 2
#> 6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1 1 2

Created on 2019-10-13 by the reprex package (v0.3.0)

Now suppose I have this list as an expression, for example, like this list_expr <- expr(list(a = 1, b= 2)). How can I pass this list expression to mutate and get the same result

library(rlang)
list_expr <- expr(list(a = 1, b= 2))
mtcars %>% mutate(!!!list_expr)
#> Warning: Unquoting language objects with `!!!` is deprecated as of rlang 0.4.0.
#> Please use `!!` instead.
#> 
#>   # Bad:
#>   dplyr::select(data, !!!enquo(x))
#> 
#>   # Good:
#>   dplyr::select(data, !!enquo(x))    # Unquote single quosure
#>   dplyr::select(data, !!!enquos(x))  # Splice list of quosures
#> 
#> This warning is displayed once per session.
#> Error: Column `list(a = 1, b = 2)` must be length 32 (the number of rows) or one, not 2
mtcars %>% mutate(!!list_expr)
#> Error: Column `list(a = 1, b = 2)` must be length 32 (the number of rows) or one, not 2

Created on 2019-10-13 by the reprex package (v0.3.0)

Hi @ruser3. You can use eval to trigger the evaluation of the expression.

library(tidyverse)
library(rlang)
#> 
#> Attaching package: 'rlang'
#> The following objects are masked from 'package:purrr':
#> 
#>     %@%, as_function, flatten, flatten_chr, flatten_dbl,
#>     flatten_int, flatten_lgl, flatten_raw, invoke, list_along,
#>     modify, prepend, splice
list_expr <- expr(list(a = 1, b= 2))
mtcars %>% mutate(!!!eval(list_expr))
#>     mpg cyl  disp  hp drat    wt  qsec vs am gear carb a b
#> 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 1 2
#> 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 1 2
#> 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 1 2
#> 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 1 2
#> 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 1 2
#> 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1 1 2
#> 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4 1 2
#> 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 1 2
#> 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2 1 2
#> 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4 1 2
#> 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4 1 2
#> 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3 1 2
#> 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3 1 2
#> 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3 1 2
#> 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4 1 2
#> 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4 1 2
#> 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4 1 2
#> 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1 1 2
#> 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2 1 2
#> 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1 1 2
#> 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1 1 2
#> 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2 1 2
#> 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2 1 2
#> 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4 1 2
#> 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2 1 2
#> 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1 1 2
#> 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2 1 2
#> 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2 1 2
#> 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4 1 2
#> 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6 1 2
#> 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8 1 2
#> 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2 1 2

Created on 2019-10-13 by the reprex package (v0.3.0)

1 Like

Hello @raytong thank you very much for replying. Your solution works, but how can I make it work if I want to use columns in mtcars in the passed list like:

library(rlang)
library(tidyverse)
list_expr <- expr(list(a = 1, b = 2, c = cyl*2))
mtcars %>% mutate(!!!eval(list_expr))
#> Error in eval(list_expr): object 'cyl' not found

Created on 2019-10-13 by the reprex package (v0.3.0)

@ruser3. Because you using !!! to unquote the expression, it will not evaluate in the context of the piped data frame but the data frame still exist in the environment, so specify the column of the data frame that you want with .$cyl.

library(rlang)
library(tidyverse)
list_expr <- expr(list(a = 1, b= 2, c = .$cyl*2))
mtcars %>% mutate(!!!eval(list_expr))
#>     mpg cyl  disp  hp drat    wt  qsec vs am gear carb a b  c
#> 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 1 2 12
#> 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 1 2 12
#> 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 1 2  8
#> 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 1 2 12
#> 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 1 2 16
#> 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1 1 2 12
#> 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4 1 2 16
#> 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 1 2  8
#> 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2 1 2  8
#> 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4 1 2 12
#> 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4 1 2 12
#> 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3 1 2 16
#> 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3 1 2 16
#> 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3 1 2 16
#> 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4 1 2 16
#> 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4 1 2 16
#> 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4 1 2 16
#> 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1 1 2  8
#> 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2 1 2  8
#> 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1 1 2  8
#> 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1 1 2  8
#> 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2 1 2 16
#> 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2 1 2 16
#> 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4 1 2 16
#> 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2 1 2 16
#> 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1 1 2  8
#> 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2 1 2  8
#> 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2 1 2  8
#> 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4 1 2 16
#> 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6 1 2 12
#> 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8 1 2 16
#> 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2 1 2  8

Created on 2019-10-13 by the reprex package (v0.3.0)

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.