Конечно, есть лучший способ сделать то, что вы пытаетесь сделать, не требующий изменения функций. При этом вы определенно не хотите заменять переменные регулярными выражениями, которые могут иметь всевозможные проблемы. Как правило, попытка манипулировать кодом как строками приводит к проблемам, например, функция типа tricky <- function(x, y) { tst <- "x + y"; -xx*x + yy*y }
, где строки и имена переменных перекрываются, приведет к неправильным результатам.
Вот функция, которая использует рекурсивный подход (Recall
) для обхода дерева выражений (рекурсии можно избежать, используя структуру типа "стек", но мне это кажется более сложным).
## Function to replace variables in function body
## expr is `body(f)`, keyvals is a lookup table for replacements
rep_vars <- function(expr, keyvals) {
if (!length(expr)) return()
for (i in seq_along(expr)) {
if (is.call(expr[[i]])) expr[[i]][-1L] <- Recall(expr[[i]][-1L], keyvals)
if (is.name(expr[[i]]) && deparse(expr[[i]]) %in% names(keyvals))
expr[[i]] <- as.name(keyvals[[deparse(expr[[i]])]])
}
return( expr )
}
## Test it
f <- function(x, y) -x^2 + x + -y^2 + y
newvals <- c('x'='x0', 'y'='y0') # named lookup vector
newbod <- rep_vars(body(f), newvals)
newbod
# -x0^2 + x0 + -y0^2 + y0
## Rename the formals, and update the body
formals(f) <- pairlist(x0=bquote(), y0=bquote())
body(f) <- newbod
## The new 'f'
f
# function (x0, y0)
# -x0^2 + x0 + -y0^2 + y0
f(2, 2)
# [1] -4
С более сложной функцией, где вы хотите избежать изменения строк или других переменных с именами, например, yy
и xx
,
tricky <- function(x, y) { tst <- "x + y"; -xx*x + yy*y }
formals(tricky) <- pairlist(x0=bquote(), y0=bquote())
body(tricky) <- rep_vars(body(tricky), newvals)
tricky
# function (x0, y0)
# {
# tst <- "x + y"
# -xx * x0 + yy * y0
# }
#
person
Rorschach
schedule
22.11.2015
Ctrl
+F
не режет его для вас? - person MichaelChirico   schedule 22.11.2015exp(x)
, и она должна выводить функцию вродеexp(x0) + exp(x0) * (x - x0)
. В промежутках происходит что-то с производными, и где-то приходится переименовывать переменные. Я делаю автоматизированную процедуру (поэтому она работает для любой функции ввода) Ctrl + F не поможет. - person Vandenman   schedule 22.11.2015