嵌套函数环境选择

day*_*yne 7 r function environment-variables

我正在编写一些用于执行重复任务的函数,但我正在尝试最小化加载数据的次数.基本上我有一个功能,它需要一些信息并制作一个情节.然后我有第二个函数循环并输出多个图到.pdf.在这两个函数中,我有以下代码行:

if(load.dat) load("myworkspace.RData")
Run Code Online (Sandbox Code Playgroud)

哪里load.dat是逻辑的,我需要的数据存储在myworkspace.RData中.当我调用循环的包装函数并输出多个图时,我不想在每次调用内部函数时重新加载工作区.我以为我可以在包装函数中加载一次工作区,然后内部函数可以访问该数据,但我得到一个错误,否则说明.

所以我的理解是当函数无法在其本地环境中找到变量时(在调用函数时创建),该函数将查找父环境中的变量.

我假设内部函数调用的父环境将是外部函数调用.显然这不是真的:

func1 <- function(...){
  print(var1)
}

func2 <- function(...){
  var1 <- "hello"
  func1(...)
}

> func2()
Error in print(var1) : object 'var1' not found
Run Code Online (Sandbox Code Playgroud)

在阅读了许多问题,语言手册和这篇真正有用的博客文章之后,我想出了以下内容:

var1 <- "hello"
save(list="var1",file="test.RData")
rm(var1)

func3 <- function(...){
  attach("test.RData")
  func1(...)
  detach("file:test.RData")
}

> func3()
[1] "hello"
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?为什么不在被调用func1的本地环境中查找未定义的变量?func2func2func1

注意:我不知道如何命名这个问题.如果有人有更好的建议,我会改变它并编辑这一行.

Fer*_*aft 8

要说明词法范围,请考虑以下事项:

首先让我们创建一个沙盒环境,只是为了避免这么常见的R_GlobalEnv:

sandbox <-new.env()
Run Code Online (Sandbox Code Playgroud)

现在我们在其中放入两个函数:f,它查找名为的变量x; 并且g,它定义了一个本地x和调用f:

sandbox$f <- function()
{
    value <- if(exists("x")) x else "not found."
    cat("This is function f looking for symbol x:", value, "\n")
}

sandbox$g <- function()
{
    x <- 123
    cat("This is function g. ")
    f()
}
Run Code Online (Sandbox Code Playgroud)

技术性:在控制台中输入功能定义会导致将封闭环境设置为R_GlobalEnv,因此我们手动强制它们的外壳fg匹配它们"所属"的环境:

environment(sandbox$f) <- sandbox
environment(sandbox$g) <- sandbox
Run Code Online (Sandbox Code Playgroud)

打电话g.x=123找不到局部变量f:

> sandbox$g()
This is function g. This is function f looking for symbol x: not found. 
Run Code Online (Sandbox Code Playgroud)

现在我们x在全球环境中创建并调用g.该函数fx首先在沙箱中查找,然后在沙箱的父级中查找,恰好是R_GlobalEnv:

> x <- 456
> sandbox$g()
This is function g. This is function f looking for symbol x: 456 
Run Code Online (Sandbox Code Playgroud)

只是为了检查f查找x首先在它的外壳,我们可以把一个x存在,并呼吁g:

> sandbox$x <- 789
> sandbox$g()
This is function g. This is function f looking for symbol x: 789 
Run Code Online (Sandbox Code Playgroud)

结论:R中的符号查找遵循封闭环境链,而不是嵌套函数调用执行期间创建的评估框架.

编辑:只需添加链接到Martin Morgan关于parent.frame()vs 的相关主题的这个非常有趣的答案parent.env()