Is there an R function that automatically switches from exact to partial matching only if there is no exact match

Viewed 66

I am looking for an R function (if possible in an existing, well-known package), that matches a string to a pattern and returns i) the first element that matches exactly or, if there are no exact matches ii) the first element that matches partially.

So far I tinkered something using grep:

data <- c("a", "a b", "c d e", "c d")

my_match <- function(data, pattern) {
  if (pattern %in% data) {
    return(which(pattern == data)[1])
  } else {
    return(grep(pattern, data, fixed = FALSE)[1])
  }
}

And some testcases with expected results:

my_match(data, "b")
[1] 2
my_match(data, "a")
[1] 1
my_match(data, "a b")
[1] 2
my_match(data, "c")
[1] 3
my_match(data, "e")
[1] 3
my_match(data, "c d")
[1] 4

  • Is there a preexisting function that behaves the same way?
  • If not: Are there more succinct ways to create the same behavior? (my code seems a bit cluttery..)
1 Answers

You can use match and if no hit adist with which.min.

my_match <- function(data, pattern) {
  i <- match(pattern, data)
  if(is.na(i)) {
    i <- grep(pattern, data)
    i[which.min(adist(pattern, data[i], partial=TRUE))]
  } else i
}

my_match(data, "b")
#[1] 2
my_match(data, "a")
#[1] 1
my_match(data, "a b")
#[1] 2
my_match(data, "c")
#[1] 3
my_match(data, "e")
#[1] 3
my_match(data, "c d")
#[1] 4
my_match(data, "x")
#integer(0)

There are many possibilities what could be accepted by partial matching which can be adjusted by costs in adist.

Related