R:对环境的困惑

R: confusion about environments

我是 R 的新手,正在尝试消除有关环境的一些困惑。我的问题是密切相关的,所以我就在这里问他们。

问题 1:'parent' 环境(也称为 'enclosure',通过 parent.env 访问)和 'parent frame',通过 parent.frame(n=1)?例如:

f = function() { print(environment());
    g = function() {env = environment(); print(env); print(parent.env(env)); print(parent.frame(n=1));}
g();
}

f();

调用f会给g的本地环境同样的'enclosure'和'parent frame',即f的本地环境。那有什么区别呢?

问题 2:据我所知,环境的围栏是 R 在该环境无法回答时查找某物定义的下一个地方。但是,一旦您附加环境并将其放置在搜索路径中的特定位置,它似乎就没有任何区别。考虑

Env1 = new.env();  Env2 = new.env();                          
parent.env(.GlobalEnv);  parent.env(Env2);  parent.env(Env1);  
x = "Global_value_x";    
Env1$x = "Env1_value_x";   Env1$y = "Env1_value_y";
Env2$x = "Env2_value_x";   Env2$y = "Env2_value_y";  Env2$z =    "Env2_value_z";
attach(Env2);   attach(Env1);                             
parent.env(.GlobalEnv);  parent.env(Env2);  parent.env(Env1);  
x; y; z;                        

比较第 2 行和第 7 行的输出。.GlobalEnv 的外壳已适当更改为 Env1,因为 Env1 现在位于搜索路径中的位置 2,但 Env1 的外壳仍然是 .GlobalEnv。当您调用 x、y 和 z 时,Env2 的 z 值是 returned,表明 Env1 正在将问题传递给 Env2。但是,它不应该将问题传递回它的附件,即 .GlobalEnv 吗?这当然是一件坏事,但是,当 Env1 实际上将问题传递给 Env2 时,说 .GlobalEnv 是 Env1 的外壳有什么意义?

问题 3:考虑

x = "Global_value_x";
Env1 = new.env(); Env2 = new.env();
Env2$x = "Env2_value_x";
attach(Env2); attach(Env1);
x;
Env1$x;

执行第4行后,R提醒我x已经在全局环境中定义,所以它在Env2中的值被屏蔽了。第 5 行当然 returns 是 x 的全局值。有什么办法可以取代这个吗?换句话说,将Env1放在搜索路径中的位置1?似乎拥有一个环境的全部意义在于暂时 "live" 在其中,使其成为您新的默认操作 space,并且它的值应该优先于您所做的其他事情。我意识到这本质上就是调用函数时发生的情况,为它的变量和诸如此类的东西创建一个临时的局部环境。在一般工作中,有什么方法可以在任何函数之外实现这种情况space?

此外,请注意执行第 6 行 returns NULL,因为 x 在 Env1 中未定义。但是不应该 return "Env2_value_x",因为 Env2 是搜索路径中的下一个行,而 x 实际上是在那里定义的?

最后

问题 4:是否可以在 Rstudio、搜索路径和所有内容中完全重置 R? rm(list=ls()) 当然会清除变量,你可以多次键入 detach() 来清除搜索路径,但这很烦人。 R 中是否有通用的重启命令?

非常感谢您的帮助。

1) 如果 g 是在全局环境中而不是在 f 中定义的,那么 g 的父框架将是全局环境,但是当从 f 调用 g 时,env 将是它的父框架。

2) 将对象附加到搜索路径实际上并没有附加它。而是创建一个新环境并将对象复制到其中。问题中定义的 Env1 和 Env2 环境与搜索路径上的同名环境不同。将 a 添加到 Env1 不会将 a 添加到搜索路径上的副本。

Env1$a <- 99
ls(as.environment("Env1"))
## [1] "x" "y"

搜索路径上副本的父环境与Env1的父环境不同。

parent.env(Env1)
## <environment: R_GlobalEnv>

parent.env(as.environment("Env1"))
## <environment: 0x0000000038452ff0>
## attr(,"name")
## [1] "Env2"

一般来说,最好不要使用 attach。我个人不使用它。

3) 例如,您可以定义一个环境为 Env1 的函数。在这种情况下,它将搜索从搜索路径上的那个点开始的自由变量。继续你的例子:

f <- function() x
environment(f) <- as.environment("Env1")
f()
## [1] "Env2_value_x"

4) 参见

Restart R within Rstudio

Quit and restart a clean R session from within R?

备注

建议退房:

http://blog.obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff/