Bill Denney
Bill Denney

Reputation: 835

Find Function Arguments without Defaults

How can I reliably tell if formal function arguments have a default value from outside the function?

In the below example, I'd like to ensure that the test below will not fail to find when an argument has or does not have a default value:

myfun <- function(a, b=1, ...) {}
formals(myfun)
for (n in names(formals(myfun))) {
  if (is.name(formals(myfun)[[n]])) {
    cat(n, "has no default value\n")
  } else {
    cat(n, "has a default value:", formals(myfun)[[n]], "\n")
  }
}

is.name is the best test that I've come up with, but I'd prefer to see both that it is a name and that it is empty (or better yet a more definitive test like missing would provide inside the function).

Upvotes: 5

Views: 155

Answers (1)

Mekki MacAulay
Mekki MacAulay

Reputation: 1727

You can do an empty string comparison to test if each value is empty:

myfun <- function(a, b=1, ...) {}
formals(myfun)
for (n in names(formals(myfun))) {
  if (formals(myfun)[[n]] == "") {
    cat(n, "has no default value\n")
  } else {
    cat(n, "has a default value:", formals(myfun)[[n]], "\n")
  }
}

a has no default value
b has a default value: 1
... has no default value

UPDATED FOR RARE BUT POSSIBLE CASE OF WANTING TO TREAT "" AS DEFINED DEFAULT OF EMPTY STRING:

myfun <- function(a, b=1, c="", ...) {}
formals(myfun)
for (n in names(formals(myfun))) {
  if (!nzchar(formals(myfun)[[n]]) & is.name(formals(myfun)[[n]])) {
    cat(n, "has no default value\n")
  } else {
    cat(n, "has a default value:", formals(myfun)[[n]], "\n")
  }
}

a has no default value
b has a default value: 1
c has a default value:
... has no default value

EXTRA EDIT FOR SAKE OF COMPLETENESS: To actually display the empty quote characters in the result and define formals(myfun) instead of calling it over and over:

myfun <- function(a, b=1, c="", ...) {}
myfun_args <- formals(myfun)
for (n in names(myfun_args)) {
  if (!nzchar(myfun_args[[n]]) & is.name(myfun_args[[n]])) {
    cat(n, "has no default value\n")
  } else {
        if (!nzchar(myfun_args[[n]])) 
            cat(n, "has a default value:", dQuote(myfun_args[[n]]), "\n")
        else
            cat(n, "has a default value:", myfun_args[[n]], "\n")
  }

}

a has no default value
b has a default value: 1
c has a default value: “”
... has no default value

Upvotes: 5

Related Questions