Сопоставление вектора значений по умолчанию с помощью match.arg () с ошибкой или без нее [R]

я хочу написать функцию, которая применяет один из двух различных статистических методов к ее входу. В процессе я заметил некоторое поведение различных функций, которые я не понимаю. Функция, которую я хочу написать, должна иметь следующие свойства:

  • он должен иметь вектор в качестве значения по умолчанию (чтобы пользователь мог видеть, какие методы доступны)
  • если аргумент остается по умолчанию, то первый из двух методов должен быть используется
  • если вручную поставляет вектор методов, тогда функция должна дать ошибку

в принципе, я хочу, чтобы функция вела себя как cor в р. Там, у вас есть значение по умолчанию method = c("pearson", "kendall", "spearman"), и функции рассчитали корреляцию Пирсона, если method не указан. Если пользователь запрашивает сразу несколько методов, функция возвращает ошибку.

глядя на cor, Кажется, это сделано используя match.arg(method). Это поведение проиллюстрировано здесь:

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

я попытался написать свою собственную функцию, также используя match.arg(method), но я понял, что результат чем-то отличается. Даже при выборе вектора method, функция не завершается с ошибкой, но возвращает результаты первого метода.

это показано ниже:

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

я не понимаю этого поведения, и я был бы рад, если бы вы могли помочь мне здесь. От моих попыток Google, я понимаю,что это может быть связано с нестандартной оценкой, но я пока не могу сложить два и два.

заранее спасибо, ваша помощь очень ценится!

Ура!

EDIT:

я мог бы также перефразировать свой вопрос:

какое могущественное колдовство cor сделайте это, он возвращает корреляцию Пирсона, когда method не указан, но он возвращает ошибку, когда method = c("pearson", "kendall", "spearman") - это явно указанный?

2 ответов


если choices и args то же самое в match.arg, затем возвращается первый элемент. В противном случае arg должна быть длина 1. От match.arg:

поскольку сопоставление аргументов по умолчанию установит arg на выбор, это разрешено как исключение из " длины один, если несколько.ok-правило TRUE ' и возвращает первый элемент.

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

вы можете получить желаемое поведение, используя фиктивный аргумент:

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))
}

на главный вопрос ответил @shadow (см. выше).

другой способ получить желаемое поведение для myfun выполнить проверку, если method поставляется или нет и печать ошибки, если это было явно поставляются с более чем одним элементом.

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

это обходит исключение в match.arg указал @тень, которая поставляет вектор функция не вызвать ошибки. Вместо этого дается эта ошибка сразу.