我正在开发我的第一个软件包,它针对的是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()函数无法解决旧问题,因此它是一个不同的问题。
答案 0 :(得分:4)
我认为通过option
实现所需内容的通俗方式实际上是通过lattice
实现的,例如,ascii
(尽管他们使用特殊选项)或stringsAsFactors
。
此外,这也是在基数R中完成的,例如?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()
要做你想要的你的包你需要设置一个选项,并且该函数从选项中获取它的值。然后另一个功能可以改变选项:
.onAttach
如果您希望软件包在加载时设置选项,则需要在.onLoad
中创建zzz.R
或.onAttach <- function(libname, pkgname) {
options(foo=c("A", "B", "C"))
}
函数。我的afex
个套餐会执行此操作并更改默认对比度。在您的情况下,它可能如下所示:
ascii
.onLoad
通过{{1}}完成(我不记得确切的区别,但Writing R Extensions会有所帮助)。
答案 1 :(得分:3)
优选地,功能具有以下内容:
因此,在您想要更改某个函数行为的情况下,以最佳方式更改输入参数。请参阅另一篇文章中的my answer。
您还可以使用option
来保存一些全局设置(例如,使用哪种字体,您使用的包存储在哪个PATH中),请参阅上面链接的问题中@James的答案。但是要谨慎使用这些东西,因为它使代码难以阅读。我主要将它们用于只读,即将它们设置一次(由包或用户设置),并且不允许函数更改它们。
不可读性源于这样一个事实,即函数的行为不仅仅是在本地确定的(即由直接使用它的代码),而且还有很远的设置。这使得很难通过纯粹查看调用它的代码来确定函数的功能,但是您必须挖掘更多代码才能完全理解正在发生的事情。另外,如果其他函数改变了这些选项,那么更难以预测给定函数的作用,因为它取决于函数的历史。这是我之前建议的只读选项重新发布,如果这些是只读的,那么可读性方面的一些问题就会减少。