R中可变的默认包值

问题描述:

我正在为R开发一个包,我想设置一些包宽度的默认值,以便稍后修改它们。我知道这听起来像全局变量,因此也是邪恶的,但我需要这个来控制分析和调试,并设置后端(包可以使用各种外部程序来做它的事情,我称它们为后端)。R中可变的默认包值

对于调用堆栈中的所有函数,所有这三个设置应该同时更改。例如,如果我拨打mypackage::function1(profiling = T)function1拨打电话mypackage::function2mypackage::function3我希望对于那些打电话的人来说,我也希望对其进行介绍。一种解决方案可能是做 mypackage::turn.on.profiling()并且所有的函数都引用了一些包变量,但它需要欺骗,锁定环境和类似的东西。

另一个可能是动态范围界定,通过sys.frame系列函数进行模拟(也就是说,一旦启用配置文件,对于低于该点的任何内容都会启动)。不要告诉我,在R中进行分析并不是那样工作,因为这是一种不同类型的分析,建立在现有分析之上,但是不同。

我毫不怀疑,我可以用这种或那种方式破解它,但我想知道是否有一个规范的解决方案或至少在CRAN中有这样的先例,这样我就不会重新发明*。

+0

为什么你不使用通常的调用机制的参数呢?我想你在这里试图太复杂了。 – hadley

+0

因为你可以用这个包构建相当复杂的东西,而且我不想看到函数A将分析选项传递给函数B,然后运行C等。另外,我希望能够剖析构建在此包上的程序,选项不可用或未正确实施。对于我在此处未提及的另一个选项(后端选项)也是如此,它允许您在本地或集群中计算事物。所以感谢简单的调用,但不,通常的参数传递机制在这里似乎不合适。 – piccolbo

设置包启动过程中选择另一种简单的方法就是把这些参数的环境中物体的包装,让您的turn.on.profiling般的功能修改。

# Don't export this 
.profileOptions <- new.env(parent=emptyenv()) 
.profileOptions$enabled <- FALSE 

# export this one 
profilingEnabled <- function(flag = NA) { 
    oldFlag <- .profileOptions$enabled 
    if (!is.na(flag)) { 
     .profileOptions$enabled = flag 
    } 
    oldFlag 
} 

# then use it 
profilingEnabled() # returns TRUE or FALSE 
profilingEnabled(TRUE) # enables profiling, returns previous state 
+0

我刚刚学会了以更明确的方式使用环境,并且这种解决方案并没有出现在我身上,但我对它进行了一番探索。我认为它比Joshua更模块化。另一方面,他似乎正在使用官方的,有福的选择机制,而你的是你自己的(聪明的)想法。我喜欢聪明的想法,但我也喜欢遵循编程领域的规律。你们俩都给出了很好的想法,谢谢,我会最终标出一个是正确的,但如果可以的话,我会标记出来。 – piccolbo

+0

@piccolbo - 我会说,如果你只有这样一个简单的参数,选择方式更好(至少更容易!)。如果你有一堆参数,并希望确保它们之间的一致性,那么这个解决方案更好,因为用户可以将选项设置为他想要的任何(无效)值,但是在这里,您可以控制设置的内容...... – Tommy

您可以在function1的开头设置一个选项,并在末尾或通过on.exit取消设置。喜欢的东西:

function1 <- function() { 
    op <- options()  # current state of options 
    on.exit(options(op)) # restore when function exits 
    print(getOption("mypackage.profiling")) 
    options(mypackage.profiling=TRUE) # turn on profiling 
    print(getOption("mypackage.profiling")) 
} 
options(mypackage.profiling=FALSE) 
function1() 
# [1] FALSE 
# [1] TRUE 
getOption("mypackage.profiling") 
# [1] FALSE 

您也可以通过.onLoad

+0

这是一个简单的解决方案,我不知道我可以添加自己的选项到一般的R机制。我所看到的唯一缺点是:你正在恢复所有的选项,不仅仅是被修改的选项,而且这还不止是被调用的(某些其他功能可能试图实现永久性选项更改)。这是解决方案的一个简单修复。另一个是任何人都可以篡改任何东西,我猜R在执行这种边界方面并不是那么重要,但是Tommy的解决方案似乎对它有更多的模块化。 – piccolbo