# Using tidy eval for multiple dplyr filter conditions

I'm new to tidy eval and trying to write generic functions- one thing I'm struggling with right now is writing multiple filter conditions for categorical variables. This is what I'm using right now-

``````create_expr <- function(name, val){
if(!is.null(val))
val <- paste0("c('", paste0(val, collapse = "','"), "')")
paste(name, "%in%", val)
}

my_filter <- function(df, cols, conds){
#   Args:
#     df: dataframe which is to be filtered
#     cols: list of column names which are to be filtered
#     conds: corresponding values for each column which need to be filtered

cols <- as.list(cols)
conds <- as.list(conds)

args <- mapply(create_expr, cols, conds, SIMPLIFY = F)

if(!length(args))
stop(cat("No filters provided"))

df <- df %>% filter_(paste(unlist(args), collapse = " & "))
return(df)
}

my_filter(gapminder, cols = list("continent", "country"),
conds = list("Europe", c("Albania", "France")))
``````

I want to know how this could be re-written using tidy eval practices. I've found material on using quos() for multiple arguments but as you can see I have two different lists of arguments here which need to be mapped to each other.

Any help is appreciated, Thanks!

Using the tidyverse, you could re-write that function as

``````library(dplyr)
library(purrr) # for map2()

my_filter <- function(df, cols, conds){
fp <- map2(cols, conds, function(x, y) quo((!!(as.name(x))) %in% !!y))
filter(df, !!!fp)
}

my_filter(gapminder::gapminder, cols = list("continent", "country"),
conds = list("Europe", c("Albania", "France")))
``````

This is calling the equivalent of

``````filter(gapminder, continent %in% "Europe", country %in% c("Albania", "France"))
``````

The main reason this works is that you can pass multiple arguments to `filter()` and they are implicitly combined with `&`. And `map2()` is just a tidyverse equivalent for `mapply` with two objects to iterate.

• Thank you so much for this @MrFlick . So is map2() something like an extended version of quos(), helping map two different quos() to each other? – Mridul Garg Mar 2 '18 at 19:36
• `map2` isn't related to `quos` generally speaking. It just iterates over `cols` and `conds`. and applies a function. In this case the function just happens to return a `quo` so we get a list of `quos` in the end. – MrFlick Mar 2 '18 at 19:38
{"ft_lang_label":"__label__en","ft_lang_prob":0.76495844,"math_prob":0.94322747,"size":1148,"snap":"2020-24-2020-29","text_gpt3_token_len":283,"char_repetition_ratio":0.10576923,"word_repetition_ratio":0.0,"special_character_ratio":0.2857143,"punctuation_ratio":0.1495327,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.97097147,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2020-06-01T17:28:55Z\",\"WARC-Record-ID\":\"<urn:uuid:3455805a-b1be-46cc-aa63-7127c3f210aa>\",\"Content-Length\":\"145178\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:238cf3d0-a51d-40be-8cc3-b581526584af>\",\"WARC-Concurrent-To\":\"<urn:uuid:3056943c-19ab-4a4c-ba41-6b6ffb81b088>\",\"WARC-IP-Address\":\"151.101.65.69\",\"WARC-Target-URI\":\"https://stackoverflow.com/questions/49075824/using-tidy-eval-for-multiple-dplyr-filter-conditions\",\"WARC-Payload-Digest\":\"sha1:6MPGOETOR3T5HDQVXHHG3TFB7G277P2D\",\"WARC-Block-Digest\":\"sha1:QPZX3LBWHR6LS5MWC4IMIOB7AFULLDC6\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2020/CC-MAIN-2020-24/CC-MAIN-2020-24_segments_1590347419056.73_warc_CC-MAIN-20200601145025-20200601175025-00505.warc.gz\"}"}