2010-03-16 20 views
41

比方說,我們有以下功能:有什麼方法可以編輯R中的函數?

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

而且,我們要改變下聯是:

line2 <- 2 

你會如何做呢?

一種方法是使用

fix(foo) 

和更改的功能。

另一種方法是再次寫入函數。

還有別的辦法嗎? (請記住,任務是改變第二行)

我想用某種方式將函數表示爲字符串的向量(以及字符),然後更改它的一個值,然後轉向它再次成爲一個功能。

+1

這不是通過將參數傳遞給某個函數來實現的功能嗎?請注意,您也可以將函數作爲參數傳遞。 – 2010-03-16 21:06:31

+2

嗨獅子座 - 問題是當我想改變別人做的功能時,但是在代碼裏面不必複製粘貼整個功能。 – 2010-03-16 21:22:35

+0

如果您需要編輯「內部」函數,我發現以下建議和代碼片段非常有用:[nabble:如何覆蓋替換函數包中的命名空間](http:// r.789695.n4.nabble.com/how-to-override-replace-a-function-in-a-package-namespace-td866337.html) – 2018-01-24 10:05:44

回答

21

或者看看調試功能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

fix的是,我知道這樣做的最好辦法,但你也可以使用edit和重新分配它:

foo <- edit(foo) 

這是fix內部做。如果您想要將更改重新分配給其他名稱,則可能需要執行此操作。

7

您可以使用'機身'功能。這個函數會返回函數體:

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}) 
+1

這實際上是'body <-'功能的用法。 – 2016-01-29 00:45:25

33
> body(foo)[[3]] <- substitute(line2 <- 2) 
> foo 
function (x) 
{ 
    line1 <- x 
    line2 <- 2 
    line3 <- line1 + line2 
    return(line3) 
} 

的代碼它變得更清晰(在「{」爲體(富)[[1]]每行是列表的連續元素。 )

+7

最近我被迫做類似的事情,有一件事情可以改善:你可以深入到列表中,因此對於問題情況'body(foo)[[3]] [[3]] < - 2'工作,替代品「是不必要的。 – Marek 2010-12-05 10:38:19

+0

謝謝。我認爲替代品需要保持作爲一種語言項目的表達方式。 – 2010-12-05 14:06:29

+2

如果您更換整條線,那麼是的,是必要的。一般來說:類應該匹配:我的方式工作,因爲我用數字替換數字。如果我想將'line2'替換爲'myVariable',那麼需要'as.symbol'轉換。 – Marek 2010-12-05 16:11:49

15

fixInNamespacefix一樣,用於包中的函數(包括那些尚未導出的函數)。

相關問題