列表的基本操作
> x<-list(u=2,v="abc") > x $u [1] 2 $v [1] "abc" > x$u [1] 2 函数hist()中的数据,也是通过列表保存的 > hn<-hist(Nile) > print(hn) $breaks [1] 400 500 600 700 800 900 1000 1100 1200 1300 1400 $counts [1] 1 0 5 20 25 19 12 11 6 1 $density [1] 0.0001 0.0000 0.0005 0.0020 0.0025 0.0019 0.0012 0.0011 0.0006 [10] 0.0001 $mids [1] 450 550 650 750 850 950 1050 1150 1250 1350 $xname [1] "Nile" $equidist [1] TRUE attr(,"class") [1] "histogram" #也可以用 > str(hn) List of 6 $ breaks : int [1:11] 400 500 600 700 800 900 1000 1100 1200 1300 ... $ counts : int [1:10] 1 0 5 20 25 19 12 11 6 1 $ density : num [1:10] 0.0001 0 0.0005 0.002 0.0025 0.0019 0.0012 0.0011 0.0006 0.0001 $ mids : num [1:10] 450 550 650 750 850 950 1050 1150 1250 1350 $ xname : chr "Nile" $ equidist: logi TRUE - attr(*, "class")= chr "histogram"
(1)创建列表
#列表中各组件的名称叫标签 > j<-list(name="Joe",salary=55000,union=T) > j $name [1] "Joe" $salary [1] 55000 $union [1] TRUE #标签是可选的,也可以不指定 > jalt<-list("Joe",55000,T) > jalt [[1]] [1] "Joe" [[2]] [1] 55000 [[3]] [1] TRUE #但是一般来说推荐为各个部分取名而不用默认的数值,这样使得代码更加清晰 #在使用时可以使用简称,只要不引起歧义 > j$sal [1] 55000 #因为列表是向量,所以可以用vector()创建列表 > z[["abc"]]<-3 > z $abc [1] 3
(2)列表索引
> j$salary [1] 55000 > j[["salary"]] [1] 55000 #可以用数字索引访问列表中的组件,但是要用双重中括号 > j[[2]] [1] 55000 []用于提取子集:[]可以用来提取数据结构中的一个或多个元素,并返回一个与原始结构类型相匹配的新结构 > j[2] $salary [1] 55000 [[]]用于提取单个元素或子列表:[[]]一次只能提取列表的一个组件,返回值是组件本身的类型,而不是列表 > j[[2]] [1] 55000 #只能提取列表中的一个组件 > j[[1:2]] Error in j[[1:2]] : subscript out of bounds > j2a<-j[[2]] > j2a [1] 55000 > class(j2a) [1] "numeric" > j[1:2] $name [1] "Joe" $salary [1] 55000 > class(j2) [1] "list" > str(j2) List of 1 $ salary: num 55000
(3)增加或删除列表元素
添加新的组件
> z<-list(a="abc",b=12) > z $a [1] "abc" $b [1] 12 > z$c <- "sailing" > z $a [1] "abc" $b [1] 12 $c [1] "sailing" 使用索引添加组件 > z<-list(a="abc",b=12) > z[[4]]<-28 > z[5:7]<-c(FALSE,TRUE,TRUE) > z $a [1] "abc" $b [1] 12 [[3]] NULL [[4]] [1] 28 [[5]] [1] FALSE [[6]] [1] TRUE [[7]] [1] TRUE 删除列表元素可以直接把它的值设为NULL #删除z$b之后,它之后的元素索引全部减1,例如原来的z[[4]]变成了z[[3]] > z$b<-NULL > z $a [1] "abc" [[2]] NULL [[3]] [1] 28 [[4]] [1] FALSE [[5]] [1] TRUE [[6]] [1] TRUE #把多个列表拼接成一个 > c(list("Joe","55000",T),list(5)) [[1]] [1] "Joe" [[2]] [1] "55000" [[3]] [1] TRUE [[4]] [1] 5 获取列表长度 > length(j) [1] 3
(4)访问列表元素和值
如果一个列表的各元素含有标签,就可以使用names()获取它的标签 #如果一个列表的各元素含有标签,就可以使用names()获取它的标签 > names(j) [1] "name" "salary" "union" #使用unlist()来获取列表的值 #unlist()返回的值是一个向量---这里返回的是一个字符串向量,而且向量的元素名就来自原列表的标签 > ulj<-unlist(j) > ulj name salary union "Joe" "55000" "TRUE" > class(ulj) [1] "character" #如果列表中都是数值,unlist()返回的就是数值向量 > z<-list(a=5,b=12,c=13) > y<-unlist(z) > class(y) [1] "numeric" > y a b c 5 12 13 #如果列表中既有字符串又有数值 #混合类型的数值下R选择了这些类型中能最大程度地保留它们共同特性的类型:字符串 #各种类型的优先级排序 NULL<raw<逻辑类型<整型<实数类型<复数类型<列表<表达式 > w<-list(a=5,b="xyz") > wu<-unlist(w) > class(wu) [1] "character" > wu a b "5" "xyz" 重点 #各种类型的优先级排序 NULL<raw<逻辑类型<整型<实数类型<复数类型<列表<表达式 如果把向量元素名称赋值为NULL,可以将其移除 > x<-c(1,2,4) > names(x) NULL > names(x)<-c("a","b","ab") > names(x) [1] "a" "b" "ab" > x a b ab 1 2 4 #把向量元素名称赋值为NULL,可以将其移除 > names(x)<-NULL > x [1] 1 2 4 #用名称来引用向量中的元素 > x<-c(1,2,4) > names(x)<-c("a","b","ab") > x["b"] b > w<-list(a=5,b="xyz") > wu<-unlist(w) > names(wu)<-NULL > wu [1] "5" "xyz" #unname()函数直接去掉元素名 > wun<-unname(wu) > wun [1] "5" "xyz"
(5)apply()函数
lapply()(代表list apply)与矩阵的apply()函数相似,对列表的每个组件执行特定的函数 并返回另外一个列表 > lapply(list(1:3,25:29),median) [[1]] [1] 2 [[2]] [1] 27 lapply()返回的列表可以转化为矩阵或向量的形式 sapply()(代表simplified[l]apply) > sapply(list(1:3,25:29), median) [1] 2 27 > z<-function(z) + return (c(z,z^2)) > sapply(1:8,z) [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [1,] 1 2 3 4 5 6 7 8 [2,] 1 4 9 16 25 36 49 64
(6)递归型列表
#生成包含两个组件的列表,每个组件本事都是列表 > b<-list(u=5,v=12) > c<-list(w=13) > a<-list(b,c) > a [[1]] [[1]]$u [1] 5 [[1]]$v [1] 12 [[2]] [[2]]$w [1] 13 > length(a) [1] 2 > c(list(a=1,b=2,c=list(d=5,e=9))) $a [1] 1 $b [1] 2 $c $c$d [1] 5 $c$e [1] 9 #recursive默认为FALSE,得到一个递归型列表,其中组件c是另外一个列表 #recursive=TRUE,得到的是向量,只有名称还带有原来递归的特征 > c(list(a=1,b=2,c=list(d=5,e=9)),recursive=T) a b c.d c.e 1 2 5 9