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
Post a Comment