Скажем, у нас есть следующая функция:
foo <- function(x)
{
line1 <- x
line2 <- 0
line3 <- line1 + line2
return(line3)
}
И это мы хотим изменить вторую строку, чтобы быть:
line2 <- 2
Как Вы сделали бы это?
Один путь состоит в том, чтобы использовать
fix(foo)
И измените функцию.
Иначе должен просто записать функцию снова.
Есть ли иначе? (Помните, задача состояла в том, чтобы изменить просто вторую строку),
То, что я хотел бы, для некоторого способа представить функцию как вектор строк (хорошо, символы), затем изменить один из, его - значения, и затем превратите его в функцию снова.
Или взгляните на функцию отладки trace ()
. Вероятно, это не совсем то, что вы ищете, но оно позволяет вам поиграть с изменениями и имеет приятную особенность, заключающуюся в том, что вы всегда можете вернуться к исходной функции с помощью untrace ()
. {{1} } trace ()
является частью пакета base
и поставляется с красивой и подробной справочной страницей.
Начните с вызова as.list (body (foo))
, чтобы увидеть все строки вашего кода.
as.list(body(foo))
[[1]]
`{`
[[2]]
line1 <- x
[[3]]
line2 <- 0
[[4]]
line3 <- line1 + line2
[[5]]
return(line3)
Затем вы просто определяете, что добавить к вашей функции и где это разместить, задав аргументы в trace ()
.
trace (foo, quote(line2 <- 2), at=4)
foo (2)
[1] 4
Вначале я сказал, что trace ()
может быть не совсем тем, что вы ищете, поскольку вы на самом деле не изменили свою третью строку кода, а просто переназначили значение объекту line2
в следующей вставленной строке кода. Это станет понятнее, если вы распечатаете код отслеживаемой функции
body (foo)
{
line1 <- x
line2 <- 0
{
.doTrace(line2 <- 2, "step 4")
line3 <- line1 + line2
}
return(line3)
}
fix
- лучший из известных мне способов сделать это, хотя вы также можете использовать edit
и переназначить его:
foo <- edit(foo)
Это то, что делает fix
внутренне. Вы можете сделать это, если хотите переназначить свои изменения другому имени.
Можно использовать функцию 'body'. Эта функция вернет тело функции:
fnx = function(a, b) { return(a^2 + 7*a + 9)}
body(fnx)
# returns the body of the function
Таким образом, хороший способ «редактировать» функцию — использовать «body» в левой части оператора присваивания:
body(fnx) = expression({a^2 + 11*a + 4})
> body(foo)[[3]] <- substitute(line2 <- 2)
> foo
function (x)
{
line1 <- x
line2 <- 2
line3 <- line1 + line2
return(line3)
}
("{" - это body(foo)[[1]], и каждая строка является последовательным элементом списка.)
fixInNamespace
подобно fix
, для функций в пакете (включая те, которые не были экспортированы).