14

私は常に=代わりに使用する頑固な useR で<-あり、明らかに多くの R プログラマーはこれに眉をひそめるでしょう。パッケージを元にformatR置き換え可能なパッケージを書きました。ご存知の方もいらっしゃると思いますが、数日前に CRAN で孤児になりました。今は戻ってきましたが、これに頼るのをためらっていました。を安全に置き換える別の方法があるかどうか疑問に思っています。正規表現は信頼性が低いと思われます (の関数の18 行目を参照してください) が、改善していただければ幸いです。おそらくパッケージが役立つでしょうか?=<-parserparser=<-=fun(a = 1)mask.inline()formatRcodetools

いくつかのテストケース:

# should replace
a = matrix(1, 1)
a = matrix(
  1, 1)

(a = 1)
a =
  1

function() {
  a = 1
}

# should not replace
c(
  a = 1
  )

c(
  a = c(
  1, 2))
4

3 に答える 3

4

Kohske さんは、パッケージを使用して問題を解決したパッケージにプル リクエストを送信しました。基本的な考え方は、コードをウォークスルーするようにコード ウォーカーを設定することです。関数呼び出しのシンボルとして検出されると、 に置き換えられます。これは、R の「 Lispの性質」によるものです。もちろん、の解析ツリーでは別の方法で扱われます。formatRcodetools=<-x = 1`=`(x, 1)`<-`(x, 1)=fun(x = 1)

パッケージ (>= 0.5.2)はパッケージformatRへの依存関係を取り除き、今では堅牢なはずです。parserreplace.assign

于 2012-07-04T02:04:35.357 に答える
4

この回答では正規表現を使用しています。失敗するエッジケースがいくつかありますが、ほとんどのコードでは問題ありません。完全な一致が必要な場合は、パーサーを使用する必要がありますが、問題が発生した場合はいつでも正規表現を調整できます。

気をつけて

#quoted function names
`my cr*azily*named^function!`(x = 1:10)
#Nested brackets inside functions
mean(x = (3 + 1:10))
#assignments inside if or for blocks
if((x = 10) > 3) cat("foo")
#functions running over multiple lines will currently fail
#maybe fixable with paste(original_code, collapse = "\n")
mean(
  x = 1:10
)

コードは、ページの例に基づいてい?regmatchesます。基本的な考え方は、関数の内容をプレースホルダーに交換し、置換を行ってから、関数の内容を元に戻すことです。

#Sample code.  For real case, use 
#readLines("source_file.R")
original_code <- c("a = 1", "b = mean(x = 1)")

#Function contents are considered to be a function name, 
#an open bracket, some stuff, then a close bracket.
#Here function names are considered to be a letter or
#dot or underscore followed by optional letters, numbers, dots or 
#underscores.  This matches a few non-valid names (see ?match.names
#and warning above).
function_content <- gregexpr(
  "[[:alpha:]._][[:alnum:._]*\\([^)]*\\)", 
  original_code
)

#Take a copy of the code to modify
copy <- original_code

#Replace all instances of function contents with the word PLACEHOLDER.
#If you have that word inside your code already, things will break.
copy <- mapply(
  function(pattern, replacement, x) 
  {
    if(length(pattern) > 0) 
    {
      gsub(pattern, replacement, x, fixed = TRUE) 
    } else x
  }, 
  pattern = regmatches(copy, function_content), 
  replacement = "PLACEHOLDER", 
  x = copy,
  USE.NAMES = FALSE
)

#Replace = with <-
copy <- gsub("=", "<-", copy)

#Now substitute back your function contents
(fixed_code <- mapply(
  function(pattern, replacement, x) 
  {
      if(length(replacement) > 0) 
      {
          gsub(pattern, replacement, x, fixed = TRUE) 
      } else x
  }, 
  pattern = "PLACEHOLDER", 
  replacement = regmatches(original_code, function_content), 
  x = copy,
  USE.NAMES = FALSE
))

#Write back to your source file
#writeLines(fixed_code, "source_file_fixed.R")
于 2012-07-02T10:58:39.757 に答える
-3

置き換えるのに最も安全な(そしておそらく最も速い)方法は、置き換えるの=<-はなく、直接入力する<-ことです。

于 2012-07-01T08:20:30.353 に答える