gpt4 book ai didi

r - 嵌套函数环境选择

转载 作者:行者123 更新时间:2023-12-04 10:43:14 29 4
gpt4 key购买 nike

我正在编写一些用于执行重复任务的函数,但我试图最大限度地减少加载数据的次数。基本上我有一个函数可以获取一些信息并绘制一个图。然后我有第二个函数,它将循环遍历并将多个图输出到 .pdf。在这两个函数中,我都有以下代码行:

if(load.dat) load("myworkspace.RData")

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

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

我假设内部函数调用的父环境将是外部函数调用。显然这不是真的:
func1 <- function(...){
print(var1)
}

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

> func2()
Error in print(var1) : object 'var1' not found

在阅读了无数问题、语言手册和 this 后非常有用的博客文章,我想出了以下内容:
var1 <- "hello"
save(list="var1",file="test.RData")
rm(var1)

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

> func3()
[1] "hello"

有一个更好的方法吗?为什么不 func1在由 func2 创建的本地环境中查找 undefined variable ,当它是 func2那个叫 func1 ?

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

最佳答案

为了说明词法范围,请考虑以下内容:

首先让我们创建一个沙箱环​​境,只是为了避免如此常见的 R_GlobalEnv:

sandbox <-new.env()

现在我们将两个函数放入其中: 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()
}

技术性:在控制台中输入函数定义会导致将封闭环境设置为 R_GlobalEnv ,因此我们手动强制 fg 的 shell 匹配它们“属于”的环境:
environment(sandbox$f) <- sandbox
environment(sandbox$g) <- sandbox

调用 gx=123 找不到局部变量 f :
> sandbox$g()
This is function g. This is function f looking for symbol x: not found.

现在我们在全局环境中创建一个 x 并调用 g 。函数 f 将首先在沙箱中查找 x,然后在沙箱的父级中,恰好是 R_GlobalEnv:
> x <- 456
> sandbox$g()
This is function g. This is function f looking for symbol x: 456

只是为了检查 f 是否首先在其 shell 中查找 x,我们可以在其中放置一个 x 并调用 g :
> sandbox$x <- 789
> sandbox$g()
This is function g. This is function f looking for symbol x: 789

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

编辑:只需添加指向 this very interesting answer from Martin Morgan on the related subject of parent.frame() vs parent.env() 的链接

关于r - 嵌套函数环境选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18338331/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com