更改锁定包中的函数的默认值

时间:2013-03-17 13:30:15

标签: r

我正在开发我的第一个软件包,它针对的是R新用户,因此我尽量减少使用软件包所需的R技能。因此,我想要一个更改我的包中其他函数的默认值的函数。但是我收到以下错误“无法将绑定添加到锁定的环境”,这意味着包的环境被锁定,我不允许更改其功能的默认值。

这是一个抛出类似错误的例子:

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

当我尝试assignInNamespace时,我得到: bindingIsLocked(x,ns)出错:没有绑定“identity”

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 个答案:

答案 0 :(得分:4)

我认为通过option实现所需内容的通俗方式实际上是通过lattice实现的,例如,ascii(尽管他们使用特殊选项)或stringsAsFactors

此外,这也是在基数R中完成的,例如?read.table的着名和臭名昭着的默认值。

如果您查看?data.framestringsAsFactors = 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()

要做你想要的你的包你需要设置一个选项,并且该函数从选项中获取它的值。然后另一个功能可以改变选项:

.onAttach

如果您希望软件包在加载时设置选项,则需要在.onLoad中创建zzz.R.onAttach <- function(libname, pkgname) { options(foo=c("A", "B", "C")) } 函数。我的afex个套餐会执行此操作并更改默认对比度。在您的情况下,它可能如下所示:

ascii

.onLoad通过{{1}}完成(我不记得确切的区别,但Writing R Extensions会有所帮助)。

答案 1 :(得分:3)

优选地,功能具有以下内容:

  1. 输入参数
  2. 使用这些参数执行某些操作的函数体
  3. 输出参数
  4. 因此,在您想要更改某个函数行为的情况下,以最佳方式更改输入参数。请参阅另一篇文章中的my answer

    您还可以使用option来保存一些全局设置(例如,使用哪种字体,您使用的包存储在哪个PATH中),请参阅上面链接的问题中@James的答案。但是要谨慎使用这些东西,因为它使代码难以阅读。我主要将它们用于只读,即将它们设置一次(由包或用户设置),并且不允许函数更改它们。

    不可读性源于这样一个事实,即函数的行为不仅仅是在本地确定的(即由直接使用它的代码),而且还有很远的设置。这使得很难通过纯粹查看调用它的代码来确定函数的功能,但是您必须挖掘更多代码才能完全理解正在发生的事情。另外,如果其他函数改变了这些选项,那么更难以预测给定函数的作用,因为它取决于函数的历史。这是我之前建议的只读选项重新发布,如果这些是只读的,那么可读性方面的一些问题就会减少。