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
This is calling the equivalent of
The main reason this works is that you can pass multiple arguments to
filter()
and they are implicitly combined with&
. Andmap2()
is just a tidyverse equivalent formapply
with two objects to iterate.