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