2017-08-15 10 views
1

一部のコードで使用されている関数のセットを探しています。 コード内にある関数の特定

  • は、彼らが常に開放ブラケット
  • ループ文字以外の何かがなければならない
  • が指定した関数名を超える正規表現grepl("someFunction\\(", code)が続くと仮定し、関数名の前にアンダースコアまたはドット、framedata.frame(...)に見つかりません。 gsub(".","\\.",theFunctions, fixed=TRUE)

がここにあります:grepl("[^a-zA-Z_\\.]someFunction\\(", code)

  • はまだ
  • \\.で関数名にドットを交換したコードにスペースを付加することで発見されたコードの先頭で必ず関数名を作成します。これは、次の正規表現で可能です

    code <- "mean(pi); head(data.frame(A=1:5)); data_frame(7:9)" 
    funs <- c("mean", "head", "head.data.frame", "data.frame", "frame", "data_frame") 
    
    data.frame(isfound=sapply(paste0("[^a-zA-Z_\\.]",gsub(".","\\.",funs,fixed=TRUE),"\\("), 
              grepl, x=paste0(" ",code)), 
          shouldbefound=c(T,T,F,T,F,T)) 
    

    これはうまくいくと思われますが、長すぎて人が読めるものではありません。
    いくつかのコードに表示される関数のセットをより洗練された方法で確認できますか?

  • 答えて

    2

    次の方法を使用して、Rコードで使用される関数の名前を見つけることができます。関数get_functionsは、文字列として表されたコードで使用できます。ここで

    get_functions <- function(code) { 
        unname(find_functions(parse(text = code))) 
    } 
    
    find_functions <- function(x, y = vector(mode = "character", length = 0)) { 
        if (is.symbol(x)) { 
        if (is.function(eval(x))) 
         c(y, as.character(x)) 
        } else { 
        if (!is.language(x)) { 
         NULL 
        } else { 
         c(y, unlist(lapply(x, find_functions))) 
        } 
        } 
    } 
    

    式は入れ子にすることができるので、find_functionsを再帰的に呼び出されます。

    例:

    code <- "mean(pi); head(data.frame(A=1:5)); data_frame(7:9)\n paste(\"ABC\", 0x28)" 
    
    get_functions(code) 
    # [1] "mean"  "head"  "data.frame" ":"   "data_frame" ":"   "paste" 
    

    このアプローチは、それがRのパーサを使用していますので、より安全であると思われます。さらに、かっこなしの関数も見つけることができる(例えば、:)。

    関連する問題