You can run an empty comparison string to check 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
b has a default value: 1
... does not have a default value
UPDATED FOR A RARE, BUT POSSIBLE CASE OF GOOD PROCESSING "" AS DEFINED BY DEFAULT OF THE EMPTY LINE:
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
b has a default value: 1
c has a default value:
... does not have a default value
ADDITIONAL EDIT TO SAVE AUTHORITY: actually display empty quotation marks as a result and define formals(myfun) instead of calling it again and again:
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
b has a default value: 1
c has a default value: ""
... does not have a default value