Question

Is there a way to achieve partial matching in atomic vectors? I know that the $ operator does not work on atomic vectors but I thought it would be possible by using [["i", exact = FALSE]].

x <- c("a1", "a2", "a3", "b1", "b2")
names(x) <- x

x$a

just returns "$ operator is invalid for atomic vectors"

x[["a", exact=FALSE]]

returns "Object "a" not found".

Is there a way to do partial matching with atomic vectors like this?

Cheers, Zuup

Was it helpful?

Solution

I don't know of something that does exactly what you want. The following is a bit kludgy but may work for you:

x[grep("^a", names(x))]
#   a1   a2   a3 
# "a1" "a2" "a3" 

Additionally, partial matching can be done, but it only works if there is only one index entry that matches your partial index. So for example:

y <- 1:5
names(y) <- paste(letters[1:5], 1:5)
y[["a", exact=F]]
# [1] 1
names(y)[[2]] <- "a 2"  # add a second index that starts with "a"
y[["a", exact=F]]
# Error in y[["a", exact = F]] : subscript out of bounds

Finally, note that you need to quote the character string inside [[, which you didn't do in your example.

OTHER TIPS

Basically, through overloading of operators you can get any behaviour you want. With the following code the brackets are overloaded to behave the way you want them to behave:

# overload the brackets for reading out
"[.pmatch_vec" = function(obj,idx){
  origclass <- setdiff(class(obj),"pmatch_vec")
  if (length(origclass)==0) origclass <- ""
  class(obj) <- origclass
  if (!is.character(idx)) 
    return(obj[idx])
  else
    return(obj[grep(paste("^",idx,sep=""),names(obj))])
}

# overload the assignment operator []<- 
"[<-.pmatch_vec" = function(obj,idx,value){
  saveclass <- class(obj)
  origclass <- setdiff(class(obj),"pmatch_vec")
  if (length(origclass)==0) origclass <- ""
  class(obj) <- origclass
  if (!is.character(idx)) 
    obj[idx] <- value
  else
    obj[grep(paste("^",idx,sep=""),names(obj))] <- value
  class(obj) <- saveclass
  return(obj)
}

Since it is dangerous to overload the brackets in general, they were overloaded only for the defined class "pmatch_vec". Additionally note, that within these functions "pmatch_vec" is temporarily removed from the class attribute in order to avoid infinite recursion.

Here are some examples for the behaviour of atomic vectors defined to be of class "pmatch_vec":

# create some vector
A = 1:6
names(A) <- c(paste("a",1:3,sep=""),paste("b",1:3,sep=""))
# set the class
class(A) = c("pmatch_vec")

# some demonstraton
A["a"]
# a1 a2 a3
#  1  2  3

A["b"]
# b1 b2 b3
#  4  5  6

A["b"] <- 7
A
# a1 a2 a3 b1 b2 b3
#  1  2  3  7  7  7

If the vector used for indexing is not of type character, the class "pmatch_vec" behaves as if it is an ordinary atomic vector:

A[1:2] <- 8
A[1:4]
# a1 a2 a3 b1
#  8  8  3  7
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top