在R当中,比较容易理解的是list,比如
> y<-list(a=1,"noname",b=1:10,c="C") > y $a [1] 1 [[2]] [1] "noname" $b [1] 1 2 3 4 5 6 7 8 9 10 $c [1] "C" > y[2] [[1]] [1] "noname" > y[[2]] [1] "noname" > y$b [1] 1 2 3 4 5 6 7 8 9 10 > names(y) [1] "a" "" "b" "c" > y[1:3] $a [1] 1 [[2]] [1] "noname" $b [1] 1 2 3 4 5 6 7 8 9 10 |
从这里可以看出,list是一种可以容纳多种不同类型数据的容器。访问它的子变量,可以有两种方式,一是通过operator [[,一是通过operator $。而list是一种有排序的变量,所以可以通过operator [来访问其子变量,但是要注意的是,[和[[返回的值是不一样的,[返回的仍是list,而[[返回的是单一的子变量。
好了,了解了这些,我们再来理解environment就容易一些了。我们可以把environment也想象成list,但是它与list还是有很明显的不同,主要在两个方面,
- environment只能通过子变量名来访问(使用operator $ or [[),它的子变量没有排序,所以不能通过id来访问。
- environment在做为参数传入程序时,并不进行拷贝,而是传递一个地址。这就意味着我们在编写程序时可以使用environment来实现以形参的形式来对数据进行修改。
我们来看实例:
> e1<-new.env(hash=T) > e1$a<-10 > ls(e1) [1] "a" > e1$a [1] 10 > e1[["a"]] [1] 10 > e1[1] Error in e1[1] : object of type 'environment' is not subsettable > attr(e1,"foo")<-10 > e1 <environment: 0x14b75a4> attr(,"foo") [1] 10 > e1$a [1] 10 > ###将environment做为形参传递给函数 > f<-function(n,env){b<-get("a", envir=env); assign("a", b+n, envir=env)} > f(10,e1) > e1$a [1] 20 > f(10,e1) > e1$a [1] 30 > ####为函数设定环境 > f1<-function(n){n+a} > environment(f1)<-e1 > f1(10) [1] 40 > f1(20) [1] 50 > e1$a<-100 > f1(20) [1] 120 > ###使用mget批量获取environment中的子变量 > e1$b<-20 > e1$c<-"c" > mget(c("a","b","c","d"),envir=e1,ifnotfound=NA) $a [1] 100 $b [1] 20 $c [1] "c" $d [1] NA |