Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically provide a list of filters to apply via dplyr and filter_

Tags:

r

dplyr

I'd like to create a list of filters to apply to a dataframe. Something like:

filters = list(cyl=4, am=1)

and then apply that to the 'mtcars' dataframe, to get just the records with cyl=4 and am=1. I can do this:

filter_(mtcars, 
        lazyeval::interp(~ val == var, val = as.name(names(filters[1])), 
                                       var = filters[[1]]))

But that only pick up the 1st entry in the filters list.

What is the idiomatic way to apply all of the filters?

(I'm trying to create a somewhat generic function that can accept a dataframe and a criteria set and will output transformations. Right now, equality is fine for the criteria, but more general idioms would be nice)

like image 204
schnee Avatar asked Apr 09 '15 16:04

schnee


2 Answers

Define filter as

filter1 <- ~(cyl==4 & am==1)

or

filter1 <- "cyl==4 & am==1"

or

library(lazyeval)
filter1 <- lazy(cyl==4 & am==1)

and use as

mtcars %>% filter_(filter1)

Example with a function:

get_cars_with_filter <- function(my_filter) {
  mtcars %>% filter_(lazy(my_filter))
}

get_cars_with_filter(cyl==4 & am == 1)
like image 130
bergant Avatar answered Sep 28 '22 15:09

bergant


All answers here are good but if you strictly want to keep your original way of defining the filter (via a list) you can simply convert it to a string an pass it to filter_ like

filter_(mtcars, paste(names(filters), filters, sep = "==", collapse = "&"))

(with the added benefit that this allows flexibility in terms of the logical operators you use, e.g. can change collapse to "|" etc)

like image 38
konvas Avatar answered Sep 28 '22 17:09

konvas