Home > other >  Using a character object as a filter condition doesn't work
Using a character object as a filter condition doesn't work

Time:01-04

If I want to filter the mtcars data frame based on the condition that the mpg >10, the number of cylinders is equal to 4 and the horsepower is greater than 100. I can use the following code:

mtcars %>% 
  filter(mpg>10 & cyl ==4 & hp > 100)
#               mpg cyl  disp  hp drat    wt qsec vs am gear carb
# Lotus Europa 30.4   4  95.1 113 3.77 1.513 16.9  1  1    5    2
# Volvo 142E   21.4   4 121.0 109 4.11 2.780 18.6  1  1    4    2

Ok!! But if I try to create a condition as an object, I get an error:

my_string_filter_condition <- c("mpg>10 & cyl ==4 & hp > 100")

mtcars %>% 
  filter(my_string_filter_condition)
# Error in `filter()`:
# ! Problem while computing `..1 = my_string_filter_condition`.
# x Input `..1` must be a logical vector, not a character.
# Run `rlang::last_error()` to see where the error occurred.

# or

mtcars %>% 
  filter(rlang::parse_expr(my_string_filter_condition))
# Error in `filter()`:
# ! Problem while computing `..1 = rlang::parse_expr(my_string_filter_condition)`.
# Caused by error in `vec_size()`:
# ! `x` must be a vector, not a call.
# Run `rlang::last_error()` to see where the error occurred.

Please any help with it?

CodePudding user response:

parse_expr() returns an expression, you need to evaluate it:

mtcars %>%
  filter(eval(rlang::parse_expr(my_string_filter_condition)))
#               mpg cyl  disp  hp drat    wt qsec vs am gear carb
# Lotus Europa 30.4   4  95.1 113 3.77 1.513 16.9  1  1    5    2
# Volvo 142E   21.4   4 121.0 109 4.11 2.780 18.6  1  1    4    2

CodePudding user response:

Note that expressions and strings are two very different things in R. you can't just put a string anywhere and expect R to automatically parse and evaluate it for you. If you have an expression, then it's best to store that in an expression type object rather than a string. For example, you can use rlang::expr to create an expression. And then can use !! to inject that expression into a dplyr function (the !! injection only works with functions that use rlang for function call manipulation -- it is not a base R feature but it is common to most tidyverse packages)

library(dplyr)
my_string_filter_condition <- rlang::expr(mpg>10 & cyl ==4 & hp > 100)

mtcars %>% 
  filter(!!my_string_filter_condition)
#               mpg cyl  disp  hp drat    wt qsec vs am gear carb
# Lotus Europa 30.4   4  95.1 113 3.77 1.513 16.9  1  1    5    2
# Volvo 142E   21.4   4 121.0 109 4.11 2.780 18.6  1  1    4    2
  • Related