В принципе, благодаря перегрузке операторов вы можете получить любое поведение, которое хотите. С помощью следующего кода скобки перегружены, чтобы вести себя так, как вы хотите, чтобы вести себя:
# 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
Удивительная команда «grep» - это именно то, что я искал. Можно даже выполнить поиск внутри самого вектора без необходимости назначения содержимого в качестве имен. – Zuup