列表
不严格地说,列表是一个向量,其中每个元素的类型可以不同
创建列表
list
函数创建列表,列表中的元素变量的类型不限,可以是向量、矩阵,甚至函数,还可以把列表作为一个列表的元素
a_list <- list(
c(1,1,2,5,14,42),
month.abb,
matrix(c(3,-8,1,-3), nrow = 2),
asin
)
可以在创建列表时就给元素命名,或者在创建完之后再用names函数命名
the_same_list <- list(
catalan = c(1,1,2,5,14,42),
months = month.abb,
involuntary = matrix(c(3,-8,1,-3), nrow = 2),
arcsin = asin
)
names(a_list) <- c("catalan", "months", "involuntary", "arcsin")
原子变量和递归变量
由于列表具有把其它列表包含在内的能力,被认为是递归变量
与之相对,向量、矩阵和数组则是原子向量
is.recursive
is.atomic
列表的维度和算术运算
列表和向量一样也有长度,其长度是它顶层元素的数目
列表没有维度,使用dim函数会返回NULL
算术运算对列表不起作用,由于每个元素的类型可以不同,将两个列表相加或相乘没有任何意义;当两个列表中的元素类型一致时,可以对它们进行算术运算
索引列表
使用方括号,可以使用正整数、负整数、逻辑值、名称进行索引
索引的结果将生成另一个列表,[[ ]]双方括号将返回列表元素的内容
$索引
可以通过嵌套方括号或传入向量来访问嵌套元素
l[["third"]]["beta"]
l[["third"]][["beta"]]
l[[c("third", "beta")]]
当访问不存在的元素时,根据所用的索引类型,行为会有所不同
- 单方括号,返回只带一个NULL元素的列表(名称为NA)
- 双方括号或美元符号,名字错误的话会返回NULL
- 以错误的数字索引访问元素内容,抛出下标越界错误
向量和列表之间的转换
as.list
转换向量为列表
busy_beaver <- c(1, 6, 21, 107)
as.list(busy_beaver)
## [[1]]
## [1] 1
##
## [[2]]
## [1] 6
##
## [[3]]
## [1] 21
##
## [[4]]
## [1] 107
如果列表中每个元素都是标量值,则可使用之前出现过的函数as.numeric
as.character
将其转换为向量
as.numeric(list(1, 6, 21, 107))
## [1] 1 6 21 107
如果列表中包含非标量元素,这种方法将不起作用
对于这样的列表,可以用unlist
函数将其转换为向量(对于混合类型的列表,有时技术上可行,但没什么用)
unlist(prime_factors)
组合列表
c
函数既能用于拼接向量,亦能用于拼接列表
c(list(a=1, b=2), list(3))
如果用c函数来拼接列表和向量,向量在拼接之前将被转换成列表(就像用了as.list函数)
c(list(a = 1, b = 2), 3)
也可以对列表使用cbind
和rbind
函数(尽量少用),但结果中出现的对象相当奇怪
它们或是含有可能为非标量元素的矩阵,或是有维度的列表
matrix_list_hybrid <- cbind(
list(a=1, b=2),
list(c=3, list(d=4))
)
## [,1] [,2]
## a 1 3
## b 2 List,1
NULL
NULL为特殊值,表示一个空的变量,最常用于列表中,不过也会在数据框和函数参数中
在创建列表时,可能会想指定一个元素,表明它必须存在但没有赋值
NULL和NA有区别,最大的区别是NA是一个标量值,而NULL不会占用任何空间(长度为0)
length(NULL)
## [1] 0
length(NA)
## [1] 1
is.null
函数测试变量是否为NULL值
因为NULL的长度为0,所以无法测试它是否为缺失值
NULL也可以用于删除列表中的元素,把元素设置为NULL则会删除它
a_list$element <- NULL
要将现有元素设置为NULL值,需使用list(NULL)
来设置
a_list$element <- list(NULL)
成对列表
成对列表 pairlist,只在内部使用,用于将参数传递到函数中,一般不会主动用到它
成对列表唯一被显式调用的情形: 使用formals
时,返回一个函数参数的成对列表
arguments_of_sd <- formals(sd)
## $x
##
##
## $na.rm
## [1] FALSE
class(arguments_of_sd)
## [1] "pairlist"
在实际使用中,成对列表和列表几乎一样
唯一的区别是,长度为0的成对列表为NULL,而长度为0的列表是一个空列表
pairlist()
## NULL
list()
## list()