Within a function that uses non-standard evaluation, check if the arguments are missing and whether a column exists

122 Views Asked by At

I'm attempting to write a function that does two things.

  1. It checks whether or not the arguments are supplied. If certain arguments are not supplied by the user it returns a custom error message.
  2. Assuming all arguments are supplied, the function then checks if certain columns are in a data.frame or tibble. I want to note that the user is supplying the column names in the function. If the column supplied by the user is not found in the function then it should return a custom error message

I've been able to write functions that solve both of these issues, however I can't seem to get them to work when they are put in a function together.

Here is a function I created that checks if the arguments are missing:

check_missing <- function(df, x, y, z) {
  if (rlang::is_missing(df)) {
    cli::cli_abort("{.var df} must be supplied")
  } else if (rlang::is_missing(x)) {
    cli::cli_abort("{.var x} must be supplied")
  } else if (rlang::is_missing(y)) {
    cli::cli_abort("{.var y} must be supplied")
  } else if (rlang::is_missing(z)) {
    cli::cli_abort("{.var z} must be supplied")
  }
}

I've also been able to create a function that checks if the values supplied by the user are found in the data.frame or tibble they also provide from this Stack Overflow question. Here is the function:

check_column <- function(df, x, y, z) {
  
  var_x <- rlang::enquo(x) %>% rlang::as_label()
  var_y <- rlang::enquo(y) %>% rlang::as_label()
  var_z <- rlang::enquo(z) %>% rlang::as_label()

   if (!var_x %in% colnames(df)) {
     cli::cli_abort("{var_x} not found object supplied in {.var df}")
   } else if (!var_y %in% colnames(df)) {
     cli::cli_abort("{var_y} not found object supplied in {.var df}")
   } else if (!var_z %in% colnames(df)) {
     cli::cli_abort("{var_z} not found object supplied in {.var df}")
   }
}

This is how check_column would work:

# create the dataframe
df <- tibble(a = 1:4, b = 9:12, c = 5:8)

# here I am supplying an imaginary variable called "banana" not in the df
check_column(df = df, x = a, y = b, z = banana)

In this example, you'll get an error message that says "banana not found in object supplied in df"

However, when we try to combine these together, it does not work. I get an error saying "Error: object 'banana' not found". Here is the function that I tried to create by combining them:

combined_fun <- function(df, x, y, z) {
  # check if the arguments are missing
  if (rlang::is_missing(df)) {
    cli::cli_abort("{.var df} must be supplied")
  } else if (rlang::is_missing(x)) {
    cli::cli_abort("{.var x} must be supplied")
  } else if (rlang::is_missing(y)) {
    cli::cli_abort("{.var y} must be supplied")
  } else if (rlang::is_missing(z)) {
    cli::cli_abort("{.var z} must be supplied")
  }

  var_x <- rlang::enquo(x) %>% rlang::as_label()
  var_y <- rlang::enquo(y) %>% rlang::as_label()
  var_z <- rlang::enquo(z) %>% rlang::as_label()

   if (!var_x %in% colnames(df)) {
     cli::cli_abort("{var_x} not found object supplied in {.var df}")
   } else if (!var_y %in% colnames(df)) {
     cli::cli_abort("{var_y} not found object supplied in {.var df}")
   } else if (!var_z %in% colnames(df)) {
     cli::cli_abort("{var_z} not found object supplied in {.var df}")
   }
}
0

There are 0 best solutions below