本篇文章由 VeriMake 旧版论坛中备份出的原帖的 Markdown 源码生成
原帖标题为:关于命名空间 | 认识 R 环境
原帖网址为:https://verimake.com/topics/245 (旧版论坛网址,已失效)
原帖作者为:dawdler(旧版论坛 id = 64,注册于 2020-08-17 14:01:22)
原帖由作者初次发表于 2021-07-09 21:18:09,最后编辑于 2021-07-09 21:18:09(编辑时间可能不准确)
截至 2021-12-18 14:27:30 备份数据库时,原帖已获得 305 次浏览、0 个点赞、0 条回复
R语言
解读R语言的环境空间
1. 认识R环境
1.1 环境空间
在R语言中,所有的变量、函数以及对象都被存储在R的环境空间中,这个环境空间就类似于其它语言中“命名空间”的概念。总体来看,R语言的环境空间由一系列有层次关系的框架(frame)组成,每个环境对应一个框架,用来区别不同的运行空间(scope)。
1.2 创建一个环境
首先,我们需要安装pryr包,这是一个贴近R语言内核、可以帮助我们深层了解R的运行机制的第三方包。
##install and import pryr package
install.packages("pryr")
library(pryr)
然后我们创建一个新的环境:
注意:环境不是赋值类型的变量哦!
##syntax: new.env(hash=TRUE, parent=parent_frame(), size = 29L)
##hash: default value is true, mapped by hash table
##parent: set specific parent environment of the defined environment, specify objects to inderit
##size: initialize size of the environment
env_1 <- new.env()
print(env_1)
print(class(env_1))
print(otype(env_1))
以上代码的运行结果为:
![](https://verimake.com/assets/files/2022-02-21/1645423026-819811-38.png)
在这个环境中定义一个变量:
##define a variable a
env_1$a <- 25
print(env_1$a)
##ls(): listing variables in current environment
ls()
ls(env_1)
以上代码的运行结果为:
![](https://verimake.com/assets/files/2022-02-21/1645423049-336675-39.png)
(大家可以忽略ls()
运行出来的其他变量,这些是我在其它脚本中用到的)
ls函数有一个all.names参数,设置all.names=FALSE则不会列出以"."开头的环境对象,设置all.names=TRUE则会全部显示,这个有一点像我们在Linux系统下使用列出文件命令ls选择是否显示隐藏文件的规则。
如果要删除环境中的对象,使用rm()
函数,并且可以通过其envir
参数的设置指定特定的环境,并删除其中的特定对象。
通过以上示例,我们可以看到,env_1作为一个环境类型的变量在当前环境空间中被定义和列出,当进入到env_1环境中后,有自定义的变量a被列出。
1.3 层次结构
R语言的环境是一种有层次关系的结构,除了空环境是最顶层的环境空间,没有父空间外,其他环境空间都有父空间,也就是都有它的上一层环境,并且,子空间会继承父空间的变量。
以下是几种常见的环境类型:
- 当前环境:用户程序运行的环境空间;
- 内部环境:用户构造出来的环境,可以是通过
new.env()
函数创建的,也可以是匿名的;
- 父环境:上一层级的环境;
- 空环境:最顶层的环境空间;
- 包环境: 包封装的环境空间;
##current environment
environment()
##defined environment
env_2 <- new.env()
print(env_2)
##parent environment
print(parent.env(env_2))
##empty environment
emptyenv()
##base environment
baseenv()
以上代码的运行结果为:
![](https://verimake.com/assets/files/2022-02-21/1645423117-570175-40.png)
1.4 查看环境空间
我们可以通过调用search()
函数来查看当前环境中加载的R包,也可以调用相关函数查看指定环境及其父环境空间:
##listing packages
search()
##parent environment of env_1
parent.env(env_1)
##parent environment of current environment
env_3 <- parent.env(environment())
print(env_3)
attr(env_3,"name")
##parent environment of base environment
parent.env(baseenv())
以上代码的运行结果为:
![](https://verimake.com/assets/files/2022-02-21/1645423145-713793-41.png)
除了单个查看,我们也可以借助函数递归来打印完整的层次结构:
##check the structure by recursion
parent.call <- function(e){
print(e)
if(is.environment(e) & !identical(emptyenv(),e)){
parent.call(parent.env(e))
}
}
env_1 <- new.env()
parent.call(env_1)
以上代码的运行结果为:
![](https://verimake.com/assets/files/2022-02-21/1645423179-211873-42.png)
输出结果从上往下看就是从内到外的环境层级~
Reference:
http://blog.fens.me/r-environments/
https://wolfsonliu.github.io/archive/2016/r-xue-xi-bi-ji-r-huan-jing-xiang-guan-de-cao-zuo.html