2014-02-13 5 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"는 무한 재귀를 피하기 위해 일시적으로 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 
+0

답변 해 주셔서 감사합니다. 오버로드로 원하는대로 코드를 구부리기가 너무 쉽다는 것을 알지 못했습니다. 필자의 경우에는 패키지 내에서 작동해야하기 때문에 약간 문제가 있습니다. 그런 과부하 된 공통 연산자를 도입 할 때는 조금주의해야합니다! 하지만 당신의 충고를 계속 지키겠다. 나는 정규 코드로는 우회 할 수없는 또 다른 문제를 안고있다. :) – Zuup