tidyverse: compose filter predicates
To reuse filter predicates, wrap them in an expression (the predicate is the condition that must be TRUE
to select a row).
library(tidyverse)
library(magrittr)
mtcars <- as_tibble(mtcars)
cyl_eq_6 <- expr(cyl == 6)
Evaluate (i.e. unwrap) the predicate using !!
(i.e. bang-bang).
mtcars %>% filter(!!cyl_eq_6)
#> # A tibble: 7 x 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
#> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
#> 3 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
#> 4 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
#> 5 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
#> 6 17.8 6 168. 123 3.92 3.44 18.9 1 0 4 4
#> 7 19.7 6 145 175 3.62 2.77 15.5 0 1 5 6
Modify predicates by evaluating them and then applying a new function. Here the predicate is negated to take all rows not satisfying the predicate.
mtcars %>% filter(not(!!cyl_eq_6))
#> # A tibble: 25 x 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
#> 2 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
#> 3 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
#> 4 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
#> 5 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
#> 6 16.4 8 276. 180 3.07 4.07 17.4 0 0 3 3
#> 7 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3
#> 8 15.2 8 276. 180 3.07 3.78 18 0 0 3 3
#> 9 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4
#> 10 10.4 8 460 215 3 5.42 17.8 0 0 3 4
#> # … with 15 more rows
Reuse modified predicates by unwrapping the predicate, applying the modification (like above), and then re-wrapping the modified predicate into a new expression.
cyl_not_eq_6 <- expr(not(!!cyl_eq_6))
mtcars %>% filter(!!cyl_not_eq_6)
#> # A tibble: 25 x 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
#> 2 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
#> 3 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
#> 4 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
#> 5 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
#> 6 16.4 8 276. 180 3.07 4.07 17.4 0 0 3 3
#> 7 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3
#> 8 15.2 8 276. 180 3.07 3.78 18 0 0 3 3
#> 9 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4
#> 10 10.4 8 460 215 3 5.42 17.8 0 0 3 4
#> # … with 15 more rows
Compose/combine multiple predicates to create a new predicate.
disp_gt_200 <- expr(disp > 200)
mtcars %>% filter(!!cyl_eq_6 & !!disp_gt_200)
#> # A tibble: 2 x 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
#> 2 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
mtcars %>% filter(!!cyl_eq_6 | !!disp_gt_200)
#> # A tibble: 21 x 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
#> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
#> 3 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
#> 4 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
#> 5 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
#> 6 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
#> 7 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
#> 8 17.8 6 168. 123 3.92 3.44 18.9 1 0 4 4
#> 9 16.4 8 276. 180 3.07 4.07 17.4 0 0 3 3
#> 10 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3
#> # … with 11 more rows
Reuse composed predicates by evaluating them and re-wrapping into a new, single predicate.
cyl_eq_6_and_disp_gt_200 <- expr(!!cyl_eq_6 & !!disp_gt_200)
mtcars %>% filter(!!cyl_eq_6_and_disp_gt_200)
#> # A tibble: 2 x 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
#> 2 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
Created on 2020-03-30 by the reprex package (v0.3.0)