2013-03-17 84 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的答案。但要谨慎使用这些东西,因为它会使代码难以阅读。我主要使用它们只读,即将它们设置为一次(通过包或用户)并且不允许函数更改它们。

不可读性源于这样一个事实,即函数的行为不是单独在本地确定的(即通过代码直接与它一起工作),还可以通过远离设置来确定。这使得很难通过纯粹查看调用它的代码来确定某个函数的功能,但是您必须挖掘更多的代码才能完全理解正在发生的事情。另外,如果其他功能改变了这些选项,使得更难以预测给定功能将做什么,因为它取决于功能的历史。如果这些是只读的,那么我早些时候对只读选项的建议又回来了,但有关可读性的一些问题就减少了。