I'm writing a function with a case_when statement and I can't figure out why my is.null(x) check in the case when will not result in "I'm NULL." I've simplified my issue below, test_function1 gives the result I'd expect and test_function does not. Is this an issue with case_when or something I'm not understanding about how is.null() works? I'd like to just handle everything in the case_when statement. Any insights are appreciated, thanks!
Function calls and result:
test_function1(NULL) --> "other content"
test_function(NULL) --> character(0)
NULL has length 0, so your case_when sees the left sides of your cases have lengths of either 0 or 1, and decides the output vector should be length 0.
From the docs:
Value
A vector of length 1 or n [the length of LHS if not 1], matching the length of the logical input or output vectors, with the type (and attributes) of the first RHS. Inconsistent lengths or types will generate an error.
To expand a little bit on @nwerth's answer, part of the problem is that grepl() returns a logical vector of length 0 when its x is NULL. For comparison:
It depends on context, but parameter checking is a pretty common first step for functions. R has some built-in functions to make this easier, like missing, match.arg, and stopifnot. The last will raise an error if the conditions specified aren't true, which is frequently what you want, e.g.
f <- function(x){
stopifnot(!missing(x), !is.null(x))
x
}
f()
#> Error in f(): !missing(x) is not TRUE
f(NULL)
#> Error in f(NULL): !is.null(x) is not TRUE
f('foo')
#> [1] "foo"
You could use case_when, but I find base R control flow sufficient for these sorts of things and reserve case_when for avoiding nested ifelse constructs.
As you get into parameter checking, beware that there are several things in R that have length 0 yet are not NULL. A non-exhaustive, off-the-top-of-my-head selection:
The R Inferno is one classic source of warnings about such gotchas.
P.S. Tiny friendly tip: around here we encourage people to format their code as code to make it easier to read. You can follow the instructions in this FAQ, or just use the little </> button at the top of the posting box.