1

I have a simple silly question, but sorry for so simple.

How do I pass an arithmetic expression as a function argument?

test_func <- function(data, myexpr){
  data %>% 
    filter(!! myexpr)
}

mtcars %>% 
  test_func(myexpr =  "cyl > 6")

Thanks in advance

Tung
  • 26,371
  • 7
  • 91
  • 115
Aureliano Guedes
  • 767
  • 6
  • 22

2 Answers2

2
library(dplyr)

test_func <- function(data, myexpr){
  data %>% 
    filter(eval(parse(text  = myexpr)))
}

mtcars %>% 
  test_func(myexpr =  "cyl > 6")
Paul van Oppen
  • 1,443
  • 1
  • 9
  • 18
1

Any of these seems to work with parsing expression: parse_expr() and parse_quo()

library(rlang)
library(dplyr)

test_func1 <- function(data, myexpr){
  data %>% 
    filter(!!parse_expr(myexpr))
}

test_func2 <- function(data, myexpr){
  data %>% 
    filter(!!parse_quo(myexpr, env = global_env()))
}

mtcars %>% 
  test_func1(myexpr =  "cyl > 6")
#>                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#> Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#> Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#> Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#> Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#> Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#> Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#> Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#> AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#> Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#> Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
#> Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8

mtcars %>% 
  test_func2(myexpr =  "cyl > 6")
#>                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#> Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#> Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#> Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#> Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#> Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#> Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#> Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#> AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#> Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#> Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
#> Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8

Created on 2020-06-16 by the reprex package (v0.3.0)

Tung
  • 26,371
  • 7
  • 91
  • 115
  • 1
    Related https://stackoverflow.com/a/49470372/786542 – Tung Jun 17 '20 at 00:43
  • 2
    `parse_quosure()` is deprecated, can you please remove its mention? The usage of `parse_quo()` is the safest, I like that you supply the caller environment (of course it may or may not be the right env, this is the danger of working with strings). Now I wonder if `parse_quo()` should default to the global-env though. It's only useful for this kind of use case, and I guess global is usually the intended environment when parsing user input. – Lionel Henry Jun 17 '20 at 05:46
  • 1
    @Tung Thanks a lot. I didn't know exactly how to search this question-based on computing programming concepts. I'll update the answer to add a mention on what is deprecated as LionelHenry told us. And sorry if it has a related, anyway, mine specifies to a function even if it is quiet redundant. – Aureliano Guedes Jun 17 '20 at 06:45
  • @LionelHenry: Thanks for the suggestion! I agree with what you said about making `global-env` the default. If the users know what they are doing, they can change that option later. You can include a warning if needed. – Tung Jun 17 '20 at 16:50