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

Posted

技术标签:

【中文标题】如何在 R 中引用函数中的本地环境?【英文标题】:How can I reference the local environment within a function, in R? 【发布时间】:2012-02-05 00:21:52 【问题描述】:

[此问题已在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 是一个错误。这是因为认为.GlobalEnv(通常(总是?)search() 向量中的第一项)是搜索的正确位置。那是错误的。相反,应该参考environment(),正确的调用如下。 (注意:ix 指定data.table()search() 输出中的位置。)

tmpWeb <- foodweb(where = c(environment(),ix), prune = vecPrune, plotting = FALSE)

这出现在对this question 的回答中,在一个名为checkScriptDependencies 的函数中,它将R 脚本文件中的代码包装到一个本地函数中,然后由foodweb 分析。这是如何使用environment() 的有限示例,Tommy 已经很好地解释了如何使用它以及在此上下文中的类似功能。

【问题讨论】:

【参考方案1】:

要获取当前环境,只需调用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 的当前环境)。

【讨论】:

那是我在聊天室里说的。现在@iterator,给他打勾:) @Spacedman 你有机会。 :) 汤米,谢谢-您对正在发生的事情的详细说明很有帮助。我从 Spacedman 的聊天记录中知道答案,但不想让问题自行回答。我希望有人能像你所做的那样给出更令人信服的解释。 curEnv 与 callStack[[3]] 相同,parent 和 grandparent 与其他 callStacks 完全不同,为什么? 调用堆栈是所有调用者的环境,但这不是找到变量的地方。父环境用于此 - 并且当函数被定义时它们被链接在一起,而调用堆栈在函数被调用时被链接在一起。棘手和令人困惑,我知道...

以上是关于如何在 R 中引用函数中的本地环境?的主要内容,如果未能解决你的问题,请参考以下文章

R语言sys方法:Sys.getenv函数获取R环境变量Sys.getlocale函数获取当前系统本地信息Sys.setlocale函数设置当前系统本地信息

AWS Cloud9:在本地引用 Lambda 层

如何在本地环境中自动启动 Azure Function?

范围——如果存在同名的本地变量,如何评估父环境中的对象?

require.js+backbone 使用r.js 在本地与生产环境 一键压缩的实现方式

wamp环境下手机如何访问本地项目