1
votes

I'm writing a function and need to test whether or not a certain parameter is null in which case one thing needs to happen or is defined in which case another thing needs to happen. If it's defined, the variable will be column in a data frame. Here's a simplified example of one of my attempts

test <- function(data, variable)  {
  
  if(is.null(variable))
    print("NULL")

  else
    print("Not NULL")
}

So in this case, test(cars, NULL) will produce the desired result but test(cars, speed) will return an error ("object 'speed' not found"); test(cars, cars$speed) produces the desired result but don't want the user to have to define the parameter in this way.

I also tried changing if(is.null(variable)) in the code above to if(is.null(data$variable)) but then both test(cars, NULL) and test(cars, speed) print "NULL." I've also tried if(is.null(~variable)) but then both test(cars, NULL) and test(cars, speed) print "Not NULL."

Would be wonderful if someone could help me figure out the code for this. Thanks in advance.

EDIT:

This is a slightly simplified version of the actual function.

histogram <- function(data, variable, group = NULL)  {
  
  data %>%
    ggplot(aes({{ variable }})) +
    geom_histogram() +
    facet_wrap({{ group }})
  
}

What I would like is to be able to call: histogram(diamonds, price, cut) instead of needing to call: histogram(diamonds, price, ~cut).

My initial idea was to determine whether or not group was NULL and then in the place of print above have two different ggplot function, one which would include facet_wrap and the other which would not.

However, as noted below, what I want to do may be quite complicated so unless someone has a simply solution, I suppose I'll stick with the function as is and the require that group by prefixed with "~".

Thanks all!

1
"but don't want the user to have to define the parameter in this way" is a costly investment: non-standard evaluation (NSE) takes several extra steps to make sure you do it right and safely. I'm inferring you want the variable argument to be resolved either by itself (if the user passes a literal object) or within the context of data (such as your (cars,speed) example. I strongly suggest reading (at least) adv-r.had.co.nz/Computing-on-the-language.html. - r2evans
Thanks for this. I'll take a look. - num_39
Would be easier to help if you include your actual function rather than a dummy one with important parts included, input and expected output. - Ronak Shah

1 Answers

0
votes

We can convert the unquoted input to string with deparse/substitute and then use is.null on the column selected. If the column is not present, it returns a NULL which can be captured along with the NULL input as NULL will be converted to "NULL" which is also not a column in the data

test <- function(data, variable)  {

   variable <- deparse(substitute(variable))
   if(is.null(data[[variable]]))
        print("NULL")

    else
     print("Not NULL")
  }

-output

test(cars, speed)
#[1] "Not NULL"
test(cars, NULL)
#[1] "NULL"

EDIT: After @Rui Barradas comments