如何在R中的函数中引用本地环境?

时间:2012-01-07 18:20:47

标签: r namespaces

[此问题已在chat room, by Spacedman中得到解决,但我将来会将其发布给其他人。]

我有一个函数myFunc,它在其中创建localFunc。 (注意:这不在包中,而是在全球环境中。)我想知道搜索路径中存在localFunc的位置,因为我想通过mvbutils::foodweb进行分析。

以下是一个例子:

myFunc <- function(){
    require(data.table)
    require(mvbutils)
    localFunc <- function(x){
        return(as.data.table(x))
    }

    vecPrune <- c("localFunc",ls("package:data.table"))
    ix <- match("data.table",search())
    tmpWeb <- foodweb(where = c(1,ix), prune = vecPrune, plotting = FALSE)
    return(tmpWeb)
}

但是,拨打myFunc()似乎并不表示localFunc来电data.table()。这是不正确的 - 是什么给出了?

(注意:where参数指定搜索路径。)


更新1:正如Tommy和Spacedman指出的那样,诀窍是指定environment()。拨打foodweb()的电话是where = c(1, ix)。索引1是一个错误。这是因为.GlobalEnvsearch()经常(总是?)environment()向量中的第一项是正确的搜索位置而产生的。这是错误的。相反,应该引用ix,正确的呼叫如下。 (注意:data.table()指定search()输出中tmpWeb <- foodweb(where = c(environment(),ix), prune = vecPrune, plotting = FALSE) 的位置。)

checkScriptDependencies

这在this question的答案中出现在一个名为foodweb的函数中,该函数将R脚本文件中的代码包装到本地函数中,然后由environment()进行分析。这是如何使用{{1}}的有限示例,Tommy在此上下文中对如何使用它和类似函数给出了很好的解释。

1 个答案:

答案 0 :(得分:41)

要获取当前环境,只需致电environment()

通常,sys.frame返回当前在调用堆栈上的任何环境,sys.nframe返回调用堆栈的当前深度。 sys.frames返回调用堆栈上所有环境的列表。

environment(f)返回函数f的闭包环境(它将查找函数和全局变量)。

如果在parent.env(e)中找不到符号,

e会返回父环境。

f <- function() {
  function() list(curEnv=environment(), parent=parent.env(environment()), 
          grandParent=parent.env(parent.env(environment())), callStack=sys.frames(), 
          callStackDepth=sys.nframe())
}
g <- function(f, n=2) if (n>2) g(f, n-1) else f()

floc <- f() # generate a local function
g(floc, 3) # call it

这将调用堆栈深度为3的本地函数floc。它返回一个列表,其中包含当前环境,它的父项(f中的本地环境),以及它的祖父项(其中)已定义f,因此globalenv)。它还返回堆栈帧(环境)列表。这些是g中递归调用的环境(最后一个是floc的当前环境除外)。