在什么情况下应该使用new.env来创建新环境?

ram*_*ser 32 r

在"什么是最有用的R技巧?" (这里),我读到使用环境给出"传递参考功能".这种方法有任何限制和/或陷阱吗?

另外,一般来说,使用创建环境的优缺点是什么?这是我一直困惑的事情,所以任何清晰度或参考对我都非常有帮助.

先感谢您.

Sha*_*ane 35

虽然我同意Harlan的总体建议(即除非你了解它,否则不要使用某些东西),我会补充:

环境是R 中的一个基本概念,在我看来,非常有用(换句话说:它们值得理解!).环境对于理解与范围相关的问题非常重要.在这种情况下你应该理解的一些基本的东西:

  1. search():会告诉你工作区; 环境按优先级顺序列出.主要环境是.GlobalEnv,并且始终可以这样引用.
  2. ls():将显示环境中包含的内容
  3. attach/ detach:为对象创建新环境
  4. get,assign,<<-,和<-:你应该知道这些功能之间的差异
  5. with:一种在不附加环境的情况下处理环境的方法.

另一个指针:看看(在ggplot使用),其使用的环境中,以提供受控的继承.

最后,我要指出环境与列表非常相似:它们都可以在其中存储任何类型的对象(请参阅此问题).但是根据您的用例(例如,您是否要处理继承和优先级),列表可以更容易使用.而且您可以始终attach将列表作为环境.

编辑:如果你想看到一个proto工作的例子,ggplot看看ggplot对象的结构,它本质上是一个由环境组成的列表:

> p <- qplot(1:10, 1:10)
> str(p)
List of 8
 $ data       :'data.frame':    0 obs. of  0 variables
 $ layers     :List of 1
  ..$ :proto object 
 .. .. $ legend     : logi NA 
 .. .. $ inherit.aes: logi TRUE 
...
> class(p$layers[[1]])
[1] "proto"       "environment"
> is.environment(p$layers[[1]])
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

注意它是如何使用proto构建的,因此包含许多环境.您还可以使用绘制这些对象中的关系graph.proto.

  • 完全同意,谢恩!如果您正在构建任何大量代码,那么理解R中的环境和范围是很重要的!但这并不一定意味着您应该将环境用作数据结构. (3认同)
  • @Harlan:我完全同意.也许我应该在这方面更有力量.@John:除非你(1)理解它们并且(2)有充分理由这样做,否则不要使用环境.列表通常是更好的选择.IMO,这是避免副作用的最佳做法,除非你绝对不能! (2认同)

Har*_*lan 6

好吧,如果你不理解它们,那些你可能有一天必须阅读你的代码(包括你未来的自己)的人不理解环境,那你就不应该使用它们!它们被设计用于封装包等中的名称空间.您可以将它们用于传递引用和哈希表这一事实并不一定意味着您应该这样做.这是一个技巧.一般来说,使用深度魔术并不是真的可取,即使它使你的代码更快一些.

  • +1触及Harlan的担忧:是的,这是一种危险的用法,因为它引入了"副作用".每当你允许一个函数改变外部世界时,你就会让自己陷入意想不到的行为.http://en.wikipedia.org/wiki/Side_effect_(computer_science) (5认同)