Search code examples
rtidyverserlangquosure

How to use quotation and unquotation when calling tidyverse functions?


I don't understand how to use expressions and quotation/unquotation/quasiquotation in the context of the R tidyverse. In the following example, I thought that using the unquote (!!) operator would allow me to generate the required arguments for add_row after I evaluate expression ex. However, I get this error instead. I've read the Metaprogramming Big Picture and Quasiquotation chapters in Advanced R, but I'm still having trouble understanding how to use these features correctly.

library(tidyverse)

# create sample data
df <- data.frame(x = 1:10, y = 11:20, z = 21:30)
df
#>     x  y  z
#> 1   1 11 21
#> 2   2 12 22
#> 3   3 13 23
#> 4   4 14 24
#> 5   5 15 25
#> 6   6 16 26
#> 7   7 17 27
#> 8   8 18 28
#> 9   9 19 29
#> 10 10 20 30
mini_df <- data.frame(x = 33:35, y = 43:45, z = 53:55)
mini_df
#>    x  y  z
#> 1 33 43 53
#> 2 34 44 54
#> 3 35 45 55

# store the expression I want to call in add_row
ex <- expr(paste0(names(df),':=',paste0('mini_df$',names(mini_df)),collapse=','))

# attempt to call add_row using arguments unquoted after evaluating expression ex
add_row(df,(!! eval(ex)), .after = 3L)
#> New rows in `add_row()` must use columns that already exist:
#> * Can't find column `"x:=mini_df$x,y:=mini_df$y,z:=mini_df$z"` in `.data`.

Created on 2019-05-17 by the reprex package (v0.3.0)


Solution

  • It turns out I should have been using unquote-splicing by calling UQS() or !!! instead. I didn't need to use the eval() or expr() functions at all. Instead, the proper usage was as follows:

    library(tidyverse)
    df <- data.frame(x = 1:10, y = 11:20, z = 21:30)
    mini_df <- data.frame(x = 33:35, y = 43:45, z = 53:55)
    add_row(df,!!!mini_df, .after = 3L)
    #>     x  y  z
    #> 1   1 11 21
    #> 2   2 12 22
    #> 3   3 13 23
    #> 4  33 43 53
    #> 5  34 44 54
    #> 6  35 45 55
    #> 7   4 14 24
    #> 8   5 15 25
    #> 9   6 16 26
    #> 10  7 17 27
    #> 11  8 18 28
    #> 12  9 19 29
    #> 13 10 20 30
    

    Created on 2019-05-17 by the reprex package (v0.3.0)

    For more on unquoting and unquote-splicing see:

    Programming with dplyr - in particular, the line that states "A very useful feature of unquote-splicing is that the vector names become argument names"

    Quasiquotation