r - Conditional filtering using tidyverse -


i want filter data frame based on variable may or may not exist. expected output, want df filtered (if has filter variable), or original, unfiltered df (if variable missing).

here minimal example:

library(tidyverse) df1 <-  tribble(~a,~b,         1l,"a",         0l, "a",         0l,"b",         1l, "b") df2 <- select(df1, b) 

filtering on df1 returns required result, filtered tibble.

filter(df1, == 1) # tibble: 2 x 2           b   <int> <chr> 1     1     2     1     b 

but second 1 throws error (expectedly), variable not in df.

filter(df2, == 1) error in filter_impl(.data, quo) :    evaluation error: object 'a' not found. 

i tried filter_at, obvious choice, throws error if there no variable matches predicament.

filter_at(df2, vars(matches("a")), any_vars(. == 1l))     error: `.predicate` has no matching columns 

so, question is: there way create conditional filtering produces expected outcome, preferably within tidyverse?

as @docendo-discimus pointed out in comments, following solutions work. added rlang::has_name instead of "a" %in% names(.).

this q&a contains original idea: conditionally apply pipeline step depending on external value.

df1 %>%     filter(if(has_name("a")) == 1 else true) # tibble: 2 x 2           b   <int> <chr> 1     1     2     1     b  df2 %>%     filter(if(has_name("a")) == 1 else true) # tibble: 4 x 1       b   <chr> 1     2     3     b 4     b 

or alternatively, using {}:

df1 %>%   {if(has_name("a")) filter(., == 1l) else .}  # tibble: 2 x 2           b   <int> <chr> 1     1     2     1     b  > df2 %>% +   {if(has_name("a")) filter(., == 1l) else .} # tibble: 4 x 1       b   <chr> 1     2     3     b 4     b 

Comments

Popular posts from this blog

neo4j - finding mutual friends in a cypher statement starting with three or more persons -

php - How to remove letter in front of the word laravel -

minify - Minimizing css files -