Какие есть способы отредактировать функцию в R? - PullRequest
46 голосов
/ 16 марта 2010

Допустим, у нас есть следующая функция:

foo <- function(x)
{
    line1 <- x
    line2 <- 0
    line3 <- line1 + line2
    return(line3)
}

И что мы хотим изменить вторую строку на:

    line2 <- 2

Как бы ты это сделал?

Одним из способов является использование

fix(foo)

И измените функцию.

Другой способ - просто снова написать функцию.

Есть ли другой способ? (Помните, задачей было изменить только вторую строку)

Мне хотелось бы, чтобы какой-то способ представлял функцию в виде вектора строк (ну, символов), затем изменял одно из ее значений и затем снова превращал его в функцию.

Ответы [ 5 ]

36 голосов
/ 21 марта 2010
> body(foo)[[3]] <- substitute(line2 <- 2)
> foo
function (x) 
{
    line1 <- x
    line2 <- 2
    line3 <- line1 + line2
    return(line3)
}

("{" это body (foo) [[1]], и каждая строка является последовательным элементом списка.)

23 голосов
/ 17 марта 2010

Или взгляните на функцию отладки 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)
}
20 голосов
/ 17 марта 2010

fix - лучший из известных мне способов сделать это, хотя вы также можете использовать edit и переназначить его:

foo <- edit(foo)

Это то, что fix делает внутри. Возможно, вы захотите сделать это, если хотите переназначить ваши изменения под другим именем.

15 голосов
/ 07 июня 2010

fixInNamespace аналогично fix для функций в пакете (включая те, которые не были экспортированы).

8 голосов
/ 17 марта 2010

Вы можете использовать функцию ' body '. Эта функция вернет тело функции:

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})
...