R 更改锁定包内函数的默认值

R 更改锁定包内函数的默认值,r,R,我正在开发我的第一个软件包,它针对的是新加入R的用户,所以我试图将使用该软件包所需的R技能数量降至最低。因此,我需要一个函数来更改包中其他函数的默认值。但我得到了以下错误“无法将绑定添加到锁定的环境”,这意味着包的环境已锁定,不允许我更改其函数的默认值 下面是一个引发类似错误的示例: library(ggplot2) assign(formals(geom_point)$position, "somethingelse", pos="package:ggplot2") 当我尝试分配名称空间时,

我正在开发我的第一个软件包,它针对的是新加入R的用户,所以我试图将使用该软件包所需的R技能数量降至最低。因此,我需要一个函数来更改包中其他函数的默认值。但我得到了以下错误“无法将绑定添加到锁定的环境”,这意味着包的环境已锁定,不允许我更改其函数的默认值

下面是一个引发类似错误的示例:

library(ggplot2)
assign(formals(geom_point)$position, "somethingelse", pos="package:ggplot2")
当我尝试分配名称空间时,我得到: bindingIsLocked(x,ns)中出错:“标识”没有绑定

下面是我希望实现的一个例子

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()

default函数最好具有以下功能:

  • 输入参数
  • 一个函数体,它用这些参数做一些事情
  • 输出参数
  • 因此,在您希望更改函数行为的情况下,以最佳方式更改输入参数。参见另一篇文章的示例

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


    不可读取性源于这样一个事实,即函数的行为不仅由本地决定(即由直接使用它的代码决定),还由远处的设置决定。这使得单纯通过查看调用函数的代码很难确定函数的功能,但是您必须深入研究更多的代码才能完全理解正在发生的事情。此外,如果其他函数更改了这些选项,那么会怎样呢?这使得预测给定函数将做什么变得更加困难,因为它取决于函数的历史。我先前对只读选项的建议又回来了,如果这些选项是只读的,那么可读性方面的一些问题就会减少。

    我认为实现您想要的功能的通俗方法是通过
    选项
    ,而包实际上就是这样做的,例如
    lattice
    (尽管它们使用特殊的选项)或
    ascii

    此外,在base 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>
    
    改变它是这样实现的:

    > 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()
    

    ascii
    通过
    .onLoad
    (我不记得确切的区别是什么,但会有所帮助)。

    我没有时间写完整的答案,但看看从CRAN中删除的.Defaults包。
    > 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 <- function(libname, pkgname) {
        options(foo=c("A", "B", "C"))
    }