Timm S.
Timm S.

Reputation: 5415

R / dplyr / complex filter in function by string

I'm trying to hand over a filter with multiple arguments as a string to dplyr::filter within a function. The answers I've seen so far all concern single filter argument, not multiple ones.

Example:

myfil <- function(df, fil) {
    quo_fil <- enquo(fil)
    df <- filter(df, !! quo_fil)
    df 
}

set.seed(25)
df <- data.frame(a = sample(10, 10), b = sample(10, 10), c = sample(10, 10))

#works
filter(df, a > 3 & b > 2 & c < 8)

  a  b c
1 5  4 1
2 7 10 5
3 9  5 2
4 6  6 3

# does not work
f <- "a > 3 & b > 2 & c < 8"

myfil(df, f)

Upvotes: 1

Views: 211

Answers (2)

RobJan
RobJan

Reputation: 1441

Based on this answer you just pass normal string to filter_ function and it's work well.

myfil <- function(df, fil) {
   df <- filter_(df, fil)
   df   
}

My result:

> myfil(df, 'a > 3 & b > 2 & c < 8')
  a b c
1 8 9 7

Upvotes: 2

divibisan
divibisan

Reputation: 12155

The problem is not with the fact that you're using multiple conditions. You can see that you get the same problem with only a single condition. The issue is that enquo expects a bare expression, not a string. So this returns the expected result:

myfil(df, a > 3 & b > 2 & c < 8)

  a  b c
1 5  4 1
2 7 10 5
3 9  5 2
4 6  6 3

If you want to work with a string, you can use rlang::parse_expr to turn a string into an expression for !! to work with:

myfil <- function(df, fil) {
  quo_fil <- rlang::parse_expr(fil)
  filter(df, !!quo_fil)
}

f <- "a > 3 & b > 2 & c < 8"
myfil(df, f)

  a  b c
1 5  4 1
2 7 10 5
3 9  5 2
4 6  6 3

Upvotes: 2

Related Questions