2011-12-06 8 views
3

数ヶ月前、私はasked something similarですが、JavaScriptを使用して、指定された文字列が「有効な」Rオブジェクト名であるかどうかを確認していました。今私はRを使って同じことを達成したいと思います。これを行うには非常に良い方法があると思いますが、丁寧な(それほど難しくない)難解なR関数があるので、正規表現は最後の防衛線。何か案は?文字の値が有効なRオブジェクト名であることを確認してください

ああ、ええ、バックティックを使用して、ものは不正行為とみなされます。 =)

+0

あなただけの 'tryCatch'は最後に非常に近い、名前を持つオブジェクトを作成しようと、それは –

+0

うんを動作するかどうかを確認できました防衛のライン。 – aL3xa

+0

最後の防衛線。どうして?あなたの問題を完全に解決します。 –

答えて

9

正規表現を修正するために編集された2013-1-9。 John Chambersの "Software for Data Analysis"の456ページから取り上げられた以前の正規表現は(微妙に)不完全でした。 (htley Wickham)


ここにいくつかの問題があります。構文的に有効なすべての名前を識別するために単純な正規表現を使用できますが、その名前の一部(ifおよびwhileなど)は '予約済み'であり、割り当てることはできません。

  • 構文的に有効な名前を識別:

    [...]文字、数字、 ドットまたは下線文字で構成されています

?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

Ahh - しかし '.' **は**構文的に有効です**。 'を試してください。 < - 9;それがそうであることを見るために。 –

+0

「。」だけでなく、「..」や「...」についても? '...'は特別な意味を持ち、 '... < - 4'、そして' get( "...") 'を実行すると、正しい応答が得られます。これは確かに、いくつかの厄介な正規表現を提供するより少しトリッキーです。この特定のケースでは、 '...'は '.GlobalEnv'に格納されています。したがって、Rはそれについて怒らない。しかし、 '?Reserved'を見れば、そこに' ... 'も表示されます。とにかく、誰も、バックティックの中に包まれたほぼすべてのオブジェクト名に値を割り当てることを止めません。しかし、とにかく、 '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 - ありがとうございました。予約された名前と予約されていない名前の区別については、本当に助けになりました(どちらも構文的には有効です)。 –

関連する問題