Skip to content

match.arg

3 messages · Spencer Graves, Martin Maechler

#
Hello:

	  I'm not on the "r-devel" list, but I just modified "match.arg" from R 
1.6.2 for Windows to accept a vector for "arg".

	  Is it appropriate that I send such things to this email address for 
consideration for inclusion in a future release?

	  I just compared this with "match.arg" in S-Plus 6.1 for Windows. 
There, I got the following:

 > match.arg(c("a","b"), c("aa", "bb"))
[1] "aa" "bb"

	  However, match.arg(c("a", "b")) in a test function with "default" = 
c("aa", "bb") returned only "a";  the following returns c("aa", "bb").

Thanks for all your hard work in developing this marvelous product.

Sincerely,
Spencer Graves

match.arg <-
function (arg, choices)
{
     if (missing(choices)) {
         formal.args <- formals(sys.function(sys.parent()))
         choices <- eval(formal.args[[deparse(substitute(arg))]])
     }
#	 cat("choices =", choices, "\n")
	 for(j in 1:length(arg)){
	    if (all(arg[j] == choices))
    	     arg[j] <- choices[1]
		 else{
		    i <- pmatch(arg[j], choices)
    		 if (is.na(i))
       		  stop(paste("ARG should be one of", paste(choices, collapse = 
", "),
          		   sep = " "))
		    if (length(i) > 1)
    		     stop("there is more than one match in match.arg")
	   	 arg[j] <- choices[i]
		}
	}
	arg
}
6 days later
#
Spencer> Hello: I'm not on the "r-devel" list, but I just
    Spencer> modified "match.arg" from R 1.6.2 for Windows to
    Spencer> accept a vector for "arg".

    Spencer> 	  Is it appropriate that I send such things to
    Spencer> this email address for consideration for inclusion
    Spencer> in a future release?

yes (using "R-devel" for ...). 
But why is this current proposal really useful?
Note that I can't see reason to match more than one argument to the
*same* list of choices. `choices' already is a vector typically...

Making a function more complicated makes it also more
error-prone, so I think we'd need a good motivation for it.
E.g., your proposal below quite badly fails when
length(arg) == 0, since you've used the ``well-known to be unsafe''
1:length(arg) idiom instead of the safe  seq(length= length(arg)) one.

Regards,
Martin

    Spencer> 	  I just compared this with "match.arg" in
    Spencer> S-Plus 6.1 for Windows.  There, I got the
    Spencer> following:

    >> match.arg(c("a","b"), c("aa", "bb"))
    Spencer> [1] "aa" "bb"




    Spencer> 	  However, match.arg(c("a", "b")) in a test
    Spencer> function with "default" = c("aa", "bb") returned
    Spencer> only "a"; the following returns c("aa", "bb").

    Spencer> Thanks for all your hard work in developing this
    Spencer> marvelous product.

    Spencer> Sincerely, Spencer Graves

    match.arg <-
    function (arg, choices)
    {
	 if (missing(choices)) {
	     formal.args <- formals(sys.function(sys.parent()))
	     choices <- eval(formal.args[[deparse(substitute(arg))]])
	 }
    #	 cat("choices =", choices, "\n")
	     for(j in 1:length(arg)){
		if (all(arg[j] == choices))
		 arg[j] <- choices[1]
		     else{
			i <- pmatch(arg[j], choices)
		     if (is.na(i))
		      stop(paste("ARG should be one of", paste(choices, collapse = 
    ", "),
			       sep = " "))
			if (length(i) > 1)
			 stop("there is more than one match in match.arg")
		     arg[j] <- choices[i]
		    }
	    }
	    arg
    }
#
Thanks for your reply.

I'm trying to generalize the MASS function "stepAIC" to study the 
effects of hierarchy for both interactions and parabolic terms.  I 
include a new argument 'hierarchy = c("include", "exclude", "ignore")' 
being a 2-vector, with the first component for interaction and the 
second for parabolic terms:

	* "exclude" fails to consider A:B (or A^2) unless both A and B are 
currently in the model.  This is the current default for interactions 
but not for parabolic terms.

	* "include" forces A:B to be evaluated with 3 degrees of freedom if 
neither A nor B are currently in the model, 2 degrees of freedom if only 
1 are in the model, and 1 degree of freedom if both are currently in the 
model (assuming A and B are both either numerical variables or 2-level 
factors).  George Box says he invented response surface methods for a 
chemical plant that had only interactions.  The plan had gone through 
several general managers, who had done what they could with one factor 
at a time experiments.  I plan to analyze several Taguchi 3-level 
experiments in order to evaluate effect sparcity and the frequency with 
which both interactions and parabolic terms occur in industrial 
experimentation, and I need an automated way of doing this.

	* "ignore" means include or exclude the interaction independent of 
whether the main effect is in the model.  This is the current default 
for A^2.

I want to make "include" the default for both A:B and A^2.  In my 
revision of stepAIC, I call match.arg as follows;

	 hierarchy <- rep(match.arg(hierarchy), length=2)

What do you think?  I know that one example does not justify adding a 
rarely used option to a general tool.  However, it occurred to me that 
there might be other applications

#################

Thanks for reminding me about the "seq(length= length(arg))" 
construction.  After I sent that email, I discovered that problem, and 
added the following line right before the "for" loop:

	if((length(arg)==length(choices)) && all(arg==choices))
	      return(choices[1])

Since I had heard no reply, I decided not to issue a "correction" to an 
email that might go nowhere or might only irritate the recipients.

Thanks again for your comments and all your effort and creativity in the 
R project.

Best Wishes,
Spencer Graves
Martin Maechler wrote: