2014-02-13 67 views
0

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

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

x$a 

刚刚返回 “$操作是原子向量无效”

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

返回 “对象 ”一个“ 未找到”。

有没有办法做这样的原子载体部分匹配?

干杯, Zuup

回答

2

我不知道的东西,不正是你想要的。下面是一个有点缺憾,但可能会为你工作:

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 

最后要注意,你需要引用内部[[,你没有在你的例子做的字符串。

+0

令人敬畏的“grep”命令正是我所期待的。甚至可以在矢量本身内搜索而不必将内容分配为名称。 – Zuup

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”会暂时从类属性中删除,以避免无限递归。

下面是原子矢量定义为类“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 
+0

谢谢你的回答!我没有意识到,通过重载来按照你想要的方式弯曲代码是很容易的。这对我来说有点问题,因为它应该在一个软件包中工作,而且我对引入像这样的重载通用运算符有点谨慎!但我会记住你的建议,我会遇到另一个问题,我不能用常规代码绕开:) – Zuup