2011-12-06 2 views
3

몇 달 전 I asked something similar이지만 제공된 문자열이 "유효한"R 객체 이름인지 확인하기 위해 JavaScript를 사용하고있었습니다. 이제는 R을 사용하여 동일한 결과를 얻고 싶습니다.이 작업을 수행 할 수있는 아주 좋은 방법이 있다고 생각합니다. 정교한 R 함수를 사용하면 일반 표현이 나를 마지막 방어선으로 생각합니다. . 어떤 아이디어?문자 값이 유효한 R 객체 이름인지 확인하십시오

오, 예, 뒤로 틱을 사용하면 물건이 사기성으로 간주됩니다. =)

+0

는'그래, –

+0

작동 tryCatch' 마지막에 가까운 경우 당신은 이름으로 객체를 생성하고 볼을 시도 할 수 있습니다 방어선. – aL3xa

+0

마지막 방어선입니다. 왜?그것은 당신의 문제를 완벽하게 해결합니다. –

답변

9

수정 된 2013-1-9 정규식 수정. John Chambers의 "Software for Data Analysis"456 페이지에서 벗어난 이전 정규식이 (미묘하게) 불완전합니다. 문제의 부부가 여기에있다


(해들리 위컴을 H.T.). 간단한 정규 표현식을 사용하여 구문 론적으로 유효한 모든 이름을 식별 할 수 있지만 일부 이름 (예 : ifwhile)은 '예약'되어 있으므로 할당 할 수 없습니다.

  • 확인 구문 적으로 유효한 이름 :

    [...] 문자, 숫자로 구성하고 점이나 밑줄 문자 :

?make.names는 구문 적으로 유효한 이름을 설명 문자 또는 숫자로 시작하는 의 점으로 시작합니다. 이러한 ' ".2way' '와 같은 명칭은 유효하지 않은 [...]

여기

해당 정규 표현식 : 제한없이 구문 유효한 이름 식별

"^([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*$" 

예약되지 않은 이름을 식별하려면 기본 기능 make.names()을 활용할 수 있습니다 임의의 문자열로부터 구문 적으로 유효한 이름을 생성합니다.

isValidAndUnreserved <- function(string) { 
     make.names(string) == string 
    } 

    isValidAndUnreserved(".jjj") 
    # [1] TRUE 
    isValidAndUnreserved(" jjj") 
    # [1] FALSE 
  • 아래 코멘트에 @Hadley에 링크 the r-devel thread를 참조, 이러한 문제의 많은 설명은 함께

    isValidName <- function(string) { 
        grepl("^([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*$", string) 
    } 
    
    isValidAndUnreservedName <- function(string) { 
        make.names(string) == string 
    } 
    
    testValidity <- function(string) { 
        valid <- isValidName(string) 
        unreserved <- isValidAndUnreservedName(string) 
        reserved <- (valid & ! unreserved) 
        list("Valid"=valid, 
         "Unreserved"=unreserved, 
         "Reserved"=reserved) 
    } 
    
    testNames <- c("mean", ".j_j", "...", "if", "while", "TRUE", "NULL", 
           "_jj", " j", ".2way") 
    t(sapply(testNames, testValidity)) 
    
         Valid Unreserved Reserved 
    mean TRUE TRUE  FALSE 
    .j_j TRUE TRUE  FALSE 
    ... TRUE TRUE  FALSE 
    if TRUE FALSE  TRUE  
    while TRUE FALSE  TRUE  
    TRUE TRUE FALSE  TRUE  
    NULL TRUE FALSE  TRUE  
    _jj FALSE FALSE  FALSE 
        j FALSE FALSE  FALSE # Note: these tests are for " j", not "j" 
    .2way FALSE FALSE  FALSE 
    

모든 퍼팅.

+1

''. '이 유효한 변수 이름이고 공백이 너무 광기처럼 보입니다. 당신은 그가'_ '을 쓰지 않았으며 그것이 번역에서 없어 졌는지 확신합니까? – blahdiblah

+1

아 -하지만'.' **은 ** 문법적으로 유효합니다. '시도하십시오. <- 9; 그것을 볼 수 있습니다. –

+0

'..'뿐만 아니라'..' 또는'...'도 무엇입니까? '... '는 특별한 의미를 지니 며,'... <- 4', 그리고'get ("...")'을하면 올바른 응답을 얻습니다. 이 것은 실제로 불쾌한 정규 표현식을 제공하는 것보다 조금 더 까다 롭습니다. 이 특별한 경우에'...'는'.GlobalEnv'에 저장되기 때문에 R은 그것에 대해 호언 장담하지 않습니다. 그러나'? Reserved '를 보면'...'도 볼 수 있습니다. 어쨌든, 아무도 당신이 back-tick 안에 포장 된 거의 모든 객체 이름에 값을 할당하는 것을 멈추지 않습니다. 그러나 어쨌든'make.names'를 가리켜 주셔서 감사합니다. 나는 좋아한다! =) – aL3xa

5

조쉬 (Josh)가 말했듯이 make.names이 아마도 가장 좋은 해결책 일 것입니다. 뿐만 아니라 그것은 이상한 문장을 처리합니다, 그것은 또한 플래그 예약 것이다 단어 :

make.names(".x") # ".x" 
make.names("_x") # "X_x" 
make.names("if") # " if." 
make.names("function") # "function." 
+0

+1 - 감사의 말과 의견을 부탁드립니다. 예약 된 이름과 예약되지 않은 이름 (둘 다 _ 구문 적으로 유효 함) 사이의 구별에 대해 제게 도움이되었습니다. –

관련 문제