2013-05-11 84 views
2

是否可以包裝R函數以修改其功能?是否可以「包裝」R函數以修改其功能?

這裏有一個玩具示例來解釋我的意思。考慮一下這個功能sum2

sum2 <- function (x) if (length(x) == 1) { cat(x); sum(x) } else sum(x) 

它做什麼呢sum,用細小的改動。假設我想重新定義sum本身做什麼sum2在這裏做。我怎樣才能以通用的方式做到這一點,而不知道我正在包裝的函數的內部?

我想這樣做,暫時「修復」一個軟件包功能,而不必修改和重新安裝軟件包。我想檢查它的輸入並在輸入滿足某些條件時返回一個特殊值。

(對於那些誰是深深熟悉的數學,我正在尋找類似的東西Gayley-Villegas trick

回答

-1

沿着這些東西線已工作:

sum2 <- sum 
sum <- function (x) if (length(x) == 1) { cat(x); sum2(x) } else sum2(x) 

什麼我不知道的是我可以將sum的原始定義存儲在sum2中,所以我可以從重新定義的sum中調用它。

正如馬修所指出的,當它被稱爲base::sum時,它不會覆蓋sum

+2

這適用於某些用途。但是另一個包可能會調用'sum'作爲'base :: sum',並且不會看到你的定義。 – 2013-05-11 03:25:45

+1

對於誰低估:不是在許多情況下(即使不是全部)在實踐中運作良好的解決方案,而是如何發佈更好的解決方案?目前還沒有其他答案可以解決我遇到的實際問題。這一個做到了,所以我分享了它,而不是讓問題變得憔悴。 – Szabolcs 2013-05-13 13:26:30

5

你需要小心這個。所有包現在都有命名空間,並會在相同的命名空間中調用其他函數。從主命令提示符調用函數時,您的方法可能會工作。但包中的函數將調用原始函數,而不是您的修改。

查看assignInNamespace及相關函數的幫助,瞭解如何在名稱空間內進行更改。 trace函數是另一種修改現有函數的方法,向現有函數添加一些附加代碼。

+0

你指出這點很好。你可以用'trace'來演示如何做同樣的事情(這個玩具的例子)嗎?其實我想修改一個函數的返回值是一個滿足給定條件的輸入值。 – Szabolcs 2013-05-11 14:15:36

+0

如果你通過'edit = TRUE'使用'trace',那麼你可以編輯函數的主體。在輸入語句中放入if語句,然後修改輸出。 – 2013-05-11 15:06:30

+0

這很好理解。但是這個編輯必須是手動的,而且我的目標是對一個功能進行編程修改。想象一下:一個包函數被打破了(或者我強烈懷疑它是)。其他軟件包使用此功能。我想在包加載後暫時修復包函數,而不修改包源。即'library(somePackage)'然後運行一個腳本,該腳本自動修復'somePackage'中的一個函數,但前提是我希望(即不永久修改軟件包源)。 – Szabolcs 2013-05-12 22:26:06

相關問題