0

I am trying to create a function that conditionally uses an argument, which when used, is a column of a df.

Here is an example function:

 new_fx <- function(data, x, y, z=NULL){
  x <- ensym(x)
  y <- ensym(y)
  if ( !is.null(z)){
  z <- ensym(z)
  }
  print(head(data[[x]]))
  print(head(data[[y]]))
  if (!is.null(z)){
  print(z)
  }
 }

When z is left NULL, I would like the function to ignore z. However, when any column is passed as z, I would like it to be converted to a symbol by z<- ensym(z).

This is what happens when I try to use the function above:

new_fx(data=iris, x=Species, y=Petal.Width)

# [1] setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica
# [1] 0.2 0.2 0.2 0.2 0.2 0.4

Everything looks good when z is left NULL. But when any other argument is passed:

new_fx(data=iris, x=Species, y=Petal.Width, z=Petal.Length)

# Error in new_fx(data = iris, x = Species, y = Petal.Width, z = Petal.Length) : 
#  object 'Petal.Length' not found

For some reason, the function has issues when the ensym() call is used inside a conditional statement.

Any suggestions?

2 Answers2

2

when you check is.null(), you're evaluating the argument. Use missing() instead

library(rlang)

 new_fx <- function(data, x, y, z){
  x <- ensym(x)
  y <- ensym(y)
  if ( !missing(z)){
  z <- ensym(z)
  }
  print(head(data[[x]]))
  print(head(data[[y]]))
  if (!missing(z)){
  print(z)
  }
 }

 data(iris)
new_fx(data=iris, x=Species, y=Petal.Width)
#> [1] setosa setosa setosa setosa setosa setosa
#> Levels: setosa versicolor virginica
#> [1] 0.2 0.2 0.2 0.2 0.2 0.4
new_fx(data=iris, x=Species, y=Petal.Width, z=Petal.Length)
#> [1] setosa setosa setosa setosa setosa setosa
#> Levels: setosa versicolor virginica
#> [1] 0.2 0.2 0.2 0.2 0.2 0.4
#> Petal.Length
Ric
  • 5,362
  • 1
  • 10
  • 23
1

We may need

 new_fx <- function(data, x, y, z=NULL){
  x <- ensym(x)
  y <- ensym(y)
  
  print(head(data[[x]]))
  print(head(data[[y]]))
  if (!missing(z)){
   z<- rlang::ensym(z)
  print(z)
  }
 }

-output

> new_fx(data=iris, x=Species, y=Petal.Width, z=Petal.Length)
[1] setosa setosa setosa setosa setosa setosa
Levels: setosa versicolor virginica
[1] 0.2 0.2 0.2 0.2 0.2 0.4
Petal.Length
akrun
  • 874,273
  • 37
  • 540
  • 662