Alternative to not () inside a function
I want to detect if a variable is missing inside a function without calling the function missing()
. I found two alternatives, but both seem rough.
Alternative 1
The missing variable seems to have a class "name" of the environment class, but it seems intuitively wrong to use this construct:
a <- function(a, b){
e <- environment()
if(class(e[["b"]]) == "name")
e$b <- a
print(b)
}
Alternative 2
I think a possible solution is to use parse
and eval
, but it seems as rough as the previous solution:
a <- function(a, b){
e <- environment()
if(eval(parse(text = sprintf("missing(%s)", "b"))))
e$b <- a
print(b)
}
Background
I need this as I am changing the API and I would like to iterate over all the old argument names in ...
and send a warning that the user should update to the new parameter names. This is why missing()
doesn't work, my current setup is:
# Warnings due to interface changes in 1.0
API_changes <-
c(rowname = "rnames",
headings = "header",
halign = "align.header")
dots <- list(...)
fenv <- environment()
for (i in 1:length(API_changes)){
old_name <- names(API_changes)[i]
new_name <- API_changes[i]
if (old_name %in% names(dots)){
if (class(fenv[[new_name]]) == "name"){
fenv[[new_name]] <- dots[[old_name]]
dots[[old_name]] <- NULL
warning("Deprecated: '", old_name, "'",
" argument is now '", new_name ,"'",
" as of ver. 1.0")
}else{
stop("You have set both the old parameter name: '", old_name, "'",
" and the new parameter name: '", new_name, "'.")
}
}
}
source to share
Gosh, do I really need to point you to the appropriate record fortune
regarding eval(parse())
? Anyway, what happened to the skewed content dots<-list(...)
? This is not at all the time.
But my main answer is, you made a mistake by allowing valid or invalid arguments in entries ...
. I don't know why you set up your previous function in this way, but it is probably much cleaner and safer to eventually eliminate this construct from your updated version. There's a reason why features & packages come with help pages. As much as I approve of backward compatibility, I don't think you are doing anyone a favor. Also, it is not clear to me how or why you want the required argument to be passed through ...
. And if that isn't required, then you don't want to emulate missing
in the first place.
Your users will very quickly :-) realize that they have invalid argument names. Regardless of whether you provide this transitional set of warning messages, they either adapt or emigrate from your code to other parameters.
source to share