Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failure of match.arg for the empty string

Tags:

r

This works:

> match.arg("", choices="")
[1] ""

But:

> match.arg("", choices=c("", "blue"))
Error during wrapup: 'arg' should be one of “”, blue

Is it a bug ? Is there an easy way to make it work ?

Of course I can do a workaround, like using "none" instead of "" and then replace in case this is the matching value.

EDIT: a possible, but not perfect workaround

choices <- c("", "blue")
choices[charmatch("", table=choices)]

This returns NA if there's no matching value. Hence it remains to code an error message in this case.

like image 862
Stéphane Laurent Avatar asked Oct 29 '22 14:10

Stéphane Laurent


1 Answers

Well, since there's no option to handle this situation, I've done a modification of the match.arg function (thanks to @akrun).

I simply replaced the line

i <- pmatch(arg, choices, nomatch = 0L, duplicates.ok = TRUE)

with

i <- charmatch(arg, choices, nomatch = 0L)

This is the modified function (at least it works for the examples given in ?match.arg):

match.arg2 <- function(arg, choices, several.ok=FALSE){
  if (missing(choices)) {
    formal.args <- formals(sys.function(sys.parent()))
    choices <- eval(formal.args[[as.character(substitute(arg))]])
  }
  if (is.null(arg)) 
    return(choices[1L])
  else if (!is.character(arg)) 
    stop("'arg' must be NULL or a character vector")
  if (!several.ok) {
    if (identical(arg, choices)) 
      return(arg[1L])
    if (length(arg) > 1L) 
      stop("'arg' must be of length 1")
  }
  else if (length(arg) == 0L) 
    stop("'arg' must be of length >= 1")
  i <- charmatch(arg, choices, nomatch = 0L)
  if (all(i == 0L)) 
    stop(gettextf("'arg' should be one of %s", paste(dQuote(choices), 
                                                     collapse = ", ")), domain = NA)
  i <- i[i > 0L]
  if (!several.ok && length(i) > 1) 
    stop("there is more than one match in 'match.arg'")
  choices[i]
}
like image 60
Stéphane Laurent Avatar answered Nov 15 '22 05:11

Stéphane Laurent