Reputation: 1863
Per other answers, one can include if
statements in pipes and within dplyr
functions. However for filter
, it seems like one needs to use an else
rather than just an if
, otherwise the filter
will return nothing, calling the error:
no applicable method for 'filter_' applied to an object of class "NULL"
Which is rather misleading IMHO since I'm not using filter_
and am not personally feeding the pipe a NULL class object. Min reprex:
data(mtcars)
a <- 1
mtcars %>% filter(if (a == 1) cyl == 6) # if in filter works
a <- NA
mtcars %>% filter(if (is.na(a)) cyl == 6) # is.na in if in filter works if it evaluates to true
a <- 4
mtcars %>% filter(if (!is.na(a)) cyl == a) # !is.na works if it evaluates to true
a <- NA
mtcars %>% filter(if (!is.na(a)) cyl == a) # doesn't work if it evaluates to false
# Input `..1` must be of size 32 or 1, not size 0.
One can use else to generate an output from the filter, by selecting a filter constraint that will include all results.
mtcars %>% filter(if (!is.na(a)) cyl == a else carb > 0
There's probably a better catch-all filter constraint, and indeed probably a more elegant way of doing this in general, but I couldn't find anyone else having found this problem so if nothing else, hopefully my progress serves its usual purpose.
Any intel as to whether this is a bug, or other ways to approach this, most welcome. Thanks.
Upvotes: 3
Views: 4586
Reputation: 388982
We can return TRUE
in else
condition which will select all the rows in case the condition is FALSE
and is not dependent on the value in the column we are testing.
library(dplyr)
a <- NA
mtcars %>% filter(if(!is.na(a)) cyl == a else TRUE)
and to answer your question, yes if
would require else
part because without it, it would just return NULL
which will fail in filter
. See this example :
num <- 2
a <- if(num > 1) 'yes'
a
#[1] "yes"
a <- if(num > 3) 'yes'
a
#NULL
Hence when you use
a <- NA
mtcars %>% filter(if(!is.na(a)) cyl == a)
What actually happens is
mtcars %>% filter(NULL)
which returns the same error message.
Upvotes: 8