原子矢量中的部分匹配

时间:2014-02-13 16:48:03

标签: r vector matching

有没有办法在原子矢量中实现部分匹配?我知道$运算符不适用于原子向量,但我认为可以使用[[“i”,exact = FALSE]]。

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

x$a

只返回“$ operator对原子矢量无效”

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

将“对象”返回“未找到”。

有没有办法与这样的原子矢量进行部分匹配?

干杯, Zuup

2 个答案:

答案 0 :(得分:2)

我不知道什么能完全符合你的要求。以下是有点kludgy但可能适合你:

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

此外,可以进行部分匹配,但只有在只有一个索引条目与您的部分索引匹配时才有效。例如:

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

最后,请注意您需要引用[[中的字符串,这在您的示例中没有这样做。

答案 1 :(得分:1)

基本上,通过重载操作符,您可以获得所需的任何行为。使用以下代码,括号将被重载以按照您希望的方式运行:

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

由于一般来说重载括号是危险的,因此它们仅为定义的类“pmatch_vec”重载。另请注意,在这些函数中,“pmatch_vec”会暂时从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

如果用于索引的向量不是字符类型,则类“pmatch_vec”的行为就好像它是普通的原子向量:

A[1:2] <- 8
A[1:4]
# a1 a2 a3 b1
#  8  8  3  7