Search code examples
r

trying to obtain TRUE/FALSE response to the question "is argument name x valid for function y?"


If we use an invalid argument inside a function, an error is returned; e.g.,

tolower(c("A", "B", NA), na.rm = FALSE)

Error in tolower(c("A", "B", NA), na.rm = FALSE) : 
  unused argument (na.rm = FALSE)

Sticking to this example, is there a way to build a function to get a TRUE/FALSE answer to the question "is na.rm a valid argument for the function tolower"?

Expected behaviour:

  1. For tolower function and na.rm argument: FALSE
  2. For median function and na.rm argument: TRUE

I thought a solution might be using try and then attempting to catch the error:

result <- try(tolower(na.rm = FALSE), silent = T)
if(class(result) == "try-error"){
  error_type <- attr(result,"condition")
  !(grepl("unused argument", error_type$message) & grepl("na.rm", error_type$message))
} else TRUE
[1] FALSE

result <- try(median(na.rm = FALSE), silent = T)
if(class(result) == "try-error"){
  error_type <- attr(result,"condition")
  !(grepl("unused argument", error_type$message) & grepl("na.rm", error_type$message))   
} else TRUE
[1] TRUE

However, this solution relies on a precise error ("unused argument") to happen, and does not work in case other errors are triggered first (e.g., if I enter a function which does not exist, TRUE is erroneously returned because the error "could not find function" is detected). Moreover, this is not very flexible: I was not able to create a function which simply takes the argument and the function and performs the check.

How can I obtain a boolean response for whether an argument name is valid for a certain function?


Solution

  • You can use formalArgs for this:

    > "na.rm" %in% formalArgs(tolower)
    [1] FALSE
    > "na.rm" %in% formalArgs(median)
    [1] TRUE
    

    Edit: However, this will only work if the function does not contain the ellipsis (...). For example, the plot function accepts many graphical parameter arguments, but only x and y are actually shown by formalArgs.

    plot(1, las=1)  # las is a valid argument for plot
    

    But...

    "las" %in% formalArgs(plot)
    [1] FALSE