环境的目的是将一组名称绑定到一组值(Advanced R,第 124 页)。 R 中的环境存在于一组父/子关系中,从一个没有父级的环境开始,empty environment。它的孩子是base environment,基本R 包的环境。
当通过library() 将包加载到R 会话中时,这些包的环境插入在base environment 和global environment 之间。
global environment 是存储 R 会话中用户定义对象的环境。此环境与workspace 同义,代表 R 用户通常工作的区域。
可以使用search() 函数查看环境列表。例如,当我启动 RStudio 时,启动时加载的所有包都列在环境链中,以 base 包开头:
> # after starting R, what environments exist?
> search()
[1] ".GlobalEnv" "tools:rstudio" "package:stats" "package:graphics"
[5] "package:grDevices" "package:utils" "package:datasets" "package:methods"
[9] "Autoloads" "package:base"
>
当我加载另一个包时,它被插入到.GlobalEnv 和tools:studio 之间的环境链中。
library(randomForest)
randomForest 4.6-14
Type rfNews() to see new features/changes/bug fixes.
> search()
[1] ".GlobalEnv" "package:randomForest" "tools:rstudio"
[4] "package:stats" "package:graphics" "package:grDevices"
[7] "package:utils" "package:datasets" "package:methods"
[10] "Autoloads" "package:base"
>
当 R 解释一个对象引用时,它首先在当前环境中查找(可能是全局环境中的一个外壳),然后在父链中导航,直到找到具有原始引用中名称的对象,或者到达空旷的环境。在Advanced R中,Hadley Wickham 说明了搜索路径如下。
搜索路径很重要,因为如果两个或多个包具有同名对象,R 会使用它在搜索路径中找到的第一个匹配项来解析引用。
当新加载的包包含一个对象,该对象掩盖了先前加载的包中的对象时,R 会生成警告。例如,当我们在 RStudio 中运行 library(caret) 时,R 会生成以下消息。
> library(caret)
Loading required package: lattice
Loading required package: ggplot2
Attaching package: ‘ggplot2’
The following object is masked from ‘package:randomForest’:
margin
>
此时,对margin() 函数的引用将使用ggplot2 中的那个,而不是randomForest。但是,我们可以使用:: 运算符显式引用对象的包名,例如randomForest::margin()。
参考: Advanced R,Wickham, Hadley,CRC Press 2015。