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