2013-03-17 82 views
3

我正在開發我的第一個包,它針對的是剛接觸R的用戶,所以我正在儘量減少使用該包所需的R技能的數量。因此我想要一個函數來改變我的包內其他函數的默認值。但是我收到以下錯誤:「無法將綁定添加到鎖定的環境」,這意味着該軟件包的環境被鎖定,我不允許更改其功能的默認值。更改某個鎖定包內某個函數的默認值

這裏是拋出一個類似的錯誤示例:

library(ggplot2) 
assign(formals(geom_point)$position, "somethingelse", pos="package:ggplot2") 

當我嘗試assignInNamespace我得到: 錯誤bindingIsLocked(X,NS):沒有了 「身份」

assignInNamespace(formals(geom_point)$position,"somethingelse", pos = "package:ggplot2") 
結合

這是我希望實現的一個例子。

default <- function(x=c("A", "B", "C")){ 
     x 
     } 
default() 

change.default <- function(x){ 
formals(default)$x <<- x  # Notice the global assign 
} 

change.default(1:3) 
default() 

我知道這遠離推薦的方法,但我願意偷工減料以提高包裝的學習曲線。有沒有辦法做到這一點?

此問題已被標記爲Setting Function Defaults R on a Project Specific Basis的副本。這是一個不同的情況,因爲這個問題涉及如何讓用戶在交互式會話中更改函數的默認值 - 而不是如何實際執行。舊的問題不能用options()函數解決,因此這是一個不同的問題。

+2

我沒有時間寫完整的答案,但看看[Defaults包](http://cran.r-project.org/web/packages/Defaults/index.html)。 – 2013-03-17 14:00:13

+0

默認值包已從CRAN中刪除。 – russellpierce 2016-02-02 19:41:55

回答

4

我認爲通過option來實現你想要的東西的口語方式實際上是這樣做的,例如,lattice(儘管它們使用特殊選項)或者ascii

此外,這也在基礎R中完成,例如着名且臭名昭着的stringsAsFactors的默認值。

如果你看看?read.table?data.frame你會得到:stringsAsFactors = default.stringsAsFactors()。檢查這表明:

> default.stringsAsFactors 
function() 
{ 
    val <- getOption("stringsAsFactors") 
    if (is.null(val)) 
     val <- TRUE 
    if (!is.logical(val) || is.na(val) || length(val) != 1L) 
     stop("options(\"stringsAsFactors\") not set to TRUE or FALSE") 
    val 
} 
<bytecode: 0x000000000b068478> 
<environment: namespace:base> 

這裏的相關部分是getOption("stringsAsFactors")產生:

> getOption("stringsAsFactors") 
[1] TRUE 

改變,可以實現這樣的:

> options(stringsAsFactors = FALSE) 
> getOption("stringsAsFactors") 
[1] FALSE 

做你想做你的包需要什麼設置一個選項,該功能將其值從選項中取出。然後另一個功能可以改變的選項:

options(foo=c("A", "B", "C")) 

default <- function(x=getOption("foo")){ 
    x 
} 
default() 

change.default <- function(x){ 
    options(foo=x) 
} 

change.default(1:3) 
default() 

如果你希望你的包設置加載時,你需要在zzz.R創建.onAttach.onLoad功能的選項。例如,我的afex包執行此操作並更改默認對比度。在你的情況下,它可能看起來像下面這樣:

.onAttach <- function(libname, pkgname) { 
    options(foo=c("A", "B", "C")) 
} 

ascii通過.onLoad做它(我不記得有什麼具體的區別,但Writing R Extensions將幫助)。

3

最好,功能有以下幾點:

  1. 輸入參數
  2. 的函數體做了使用這些參數
  3. 輸出參數

所以在你的情況下,你想要改變某個函數的行爲,改變輸入參數是最好的方法。例如見my answer轉到另一篇文章。

您也可以使用option來保存一些全局設置(例如,要使用哪種字體,您使用哪個包的PATH存儲),請參閱上面鏈接的問題中@James的答案。但要謹慎使用這些東西,因爲它會使代碼難以閱讀。我主要使用它們只讀,即將它們設置爲一次(通過包或用戶)並且不允許函數更改它們。

不可讀性源於這樣一個事實,即函數的行爲不是單獨在本地確定的(即通過代碼直接與它一起工作),還可以通過遠離設置來確定。這使得很難通過純粹查看調用它的代碼來確定某個函數的功能,但是您必須挖掘更多的代碼才能完全理解正在發生的事情。另外,如果其他功能改變了這些選項,使得更難以預測給定功能將做什麼,因爲它取決於功能的歷史。如果這些是隻讀的,那麼我早些時候對只讀選項的建議又回來了,但有關可讀性的一些問題就減少了。