Corresponding vector of default values ​​using match.arg () with or without error [R]

I want to write a function that applies one of two different statistical methods to its input. In the process, I noticed some behavior of various functions that I do not understand. The function I want to write must have the following properties:

  • it should have a vector as the default value (so that the user can see which methods are available)
  • if the argument remains the default then use the first of two methods
  • if the user manually supplies a vector of methods, then the function should throw an error

Basically, I want the function to behave the way cor does in R. There you have the default value method = c("pearson", "kendall", "spearman") , and the functions calculated the Pearson correlation if method does not indicated. If the user requests several methods at once, the function returns an error.

From a look at cor this seems to be done using match.arg(method) . This behavior is illustrated here:

 x <- y <- 1:5 cor(x, y, method="pearson") # = 1 cor(x, y, method="kendall") # = 1 cor(x, y, method=c("pearson","kendall")) # gives an error 

I tried to write my own function, also using match.arg(method) , but I realized that the result is somehow different. Even when choosing a vector for method function does not end with an error, but returns the results of the first method.

This is shown here:

 myfun <- function(x, method=c("add","multiply")){ method <- match.arg(method) if(method=="add") return(sum(x)) if(method=="multiply") return(prod(x)) } x <- 1:5 myfun(x, method="add") # = 15 myfun(x, method="multiply") # = 120 myfun(x, method=c("add","multiply")) # = 15 

I do not understand this behavior, and I would be glad if you could help me here. From my attempts at Google, I understand that this may be due to a non-standard assessment, but so far I can’t add two and two.

Thanks in advance, your help is much appreciated!

Hooray!

EDIT:

I could also rephrase my question:

What powerful cor magic does cor make it return Pearson's correlation when method not supplied, but that it returns an error when method = c("pearson", "kendall", "spearman") explicitly indicated?

+6
source share
2 answers

If choices and args match in match.arg , then the first element is returned. Otherwise, arg should be length 1. From match.arg :

Since matching arguments by default will set the arg argument to be selected, this is allowed as an exception for "length one, unless multiple .ok is a TRUE rule and returns the first element.

 match.arg(c("pearson", "kendall", "spearman"), c("pearson", "kendall", "spearman")) ## [1] "pearson" match.arg(c("pearson", "kendall"), c("pearson", "kendall", "spearman")) ## Error in match.arg(c("pearson", "kendall"), c("pearson", "kendall", "spearman")) : ## 'arg' must be of length 1 

You can get the desired behavior using a dummy argument:

 myfun <- function(x, method=c("add","multiply","other.return.error")){ method <- match.arg(method) if("other.return.error" %in% method) stop("this option should not be used") if(method=="add") return(sum(x)) if(method=="multiply") return(prod(x)) } 
+6
source

@Shadow answered the main question (see above).

Another way to get the desired behavior for myfun is to check if method provided or not, and print an error if it is explicitly provided with more than one element.

 myfun <- function(x, method=c("add","multiply")){ if(!missing(method) & length(method)>1) stop("Only one 'method' allowed.") method <- match.arg(method) if(method=="add") return(sum(x)) if(method=="multiply") return(prod(x)) } x <- 1:5 myfun(x) # = 15 myfun(x, method="add") # = 15 myfun(x, method="multiply") # = 120 myfun(x, method=c("add","multiply")) # gives error 

This bypasses the exception in match.arg out by @shadow, whereby delivering a function vector cannot cause an error. Instead, this error is set immediately.

+1
source

Source: https://habr.com/ru/post/983535/


All Articles