Какие способы редактирования функции в R?
Скажем, мы имеем следующую функцию:
foo <- function(x)
{
line1 <- x
line2 <- 0
line3 <- line1 + line2
return(line3)
}
И мы хотим изменить вторую строку:
line2 <- 2
Как вы это сделаете?
Один из способов - использовать
fix(foo)
И измените функцию.
Другой способ - просто написать функцию снова.
Есть ли другой способ? (Помните, задача состояла в том, чтобы изменить только вторую строку)
Я хотел бы каким-то образом представить функцию как вектор строк (ну, символы), затем изменить одно из значений, а затем снова включить его в функцию.
Ответы
Ответ 1
Или взгляните на функцию отладки trace()
. Это, вероятно, не совсем то, что вы ищете, но оно позволяет вам играть с изменениями, и у него есть приятная функция, с которой вы всегда можете вернуться к исходной функции с помощью untrace()
.
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)
}
Ответ 2
> body(foo)[[3]] <- substitute(line2 <- 2)
> foo
function (x)
{
line1 <- x
line2 <- 2
line3 <- line1 + line2
return(line3)
}
( "{" является телом (foo) [[1]], и каждая строка является последовательным элементом списка.)
Ответ 3
fix
- это лучший способ, которым я это знаю, хотя вы также можете использовать edit
и повторно назначить его:
foo <- edit(foo)
Это то, что fix
делает внутренне. Возможно, вы захотите сделать это, если хотите повторно назначить свои изменения на другое имя.
Ответ 4
fixInNamespace
похож на fix
, для функций в пакете (включая те, которые не были экспортированы).
Ответ 5
Вы можете использовать функцию тело. Эта функция вернет тело функции:
fnx = function(a, b) { return(a^2 + 7*a + 9)}
body(fnx)
# returns the body of the function
Таким образом, хороший способ "изменить" функцию - использовать "тело" в левой части оператора присваивания:
body(fnx) = expression({a^2 + 11*a + 4})