List 在 R语言中是一种非常重要的数据结构,因为它允许存储不同类型和大小的数据项。但是R语言中的 list 和其他很多编程语言中的 listarray 不完全相同。在R中,list 被设计为一个通用的容器,可以包含任何类型的对象,包括其他的 list。因此,它更接近其他编程语言中的结构或对象,但它仍然保持了序列的特点。

上面的通用的容器指的是是 list 可以包含R中的任何类型的对象,不受限于某一种数据类型。它可以包括向量、矩阵、函数、其他 list 等,这使得 list 非常适合作为数据的组织和存储结构。而“序列”在这里的意思是,尽管 list 可以包含多种数据类型,但它仍然是一个有序的集合,即其中的元素是按照一定的顺序排列的。例如,当你创建一个 list 时,第一个元素是你添加的第一个元素,第二个是第二个,以此类推。因此,你可以通过索引号来访问 list 中的元素。

创建List

使用 list() 函数可以创建一个List。

例如:

1
2
3
4
5
6
7
8
9
10
> my_list <- list(item1=1, item2="hello", item3=c(1, 2, 3))
> my_list
$item1
[1] 1

$item2
[1] "hello"

$item3
[1] 1 2 3

又或者是:

1
2
3
4
5
6
7
8
9
10
11
> listobj <- list(x = c(3, 7, 2),
+ A = diag(c(9, 2, 1)))
> print(listobj)
$x
[1] 3 7 2

$A
[,1] [,2] [,3]
[1,] 9 0 0
[2,] 0 2 0
[3,] 0 0 1

访问 List 中的子集

在R语言中,访问List中的元素或子集有点与其他编程语言中的操作不同。尽管多数语言使用[]来访问数组或列表的元素,但在R中,由于List可以包含不同类型的元素,因此提供了两种方法来访问这些元素:[][[]]

考虑以下的例子:

1
2
3
4
5
6
7
8
9
10
11
> listobj <- list(x = c(3, 7, 2),
+ A = diag(c(9, 2, 1)))
> listobj
$x
[1] 3 7 2

$A
[,1] [,2] [,3]
[1,] 9 0 0
[2,] 0 2 0
[3,] 0 0 1

要取出 listobj 的第二个元素并保持其在列表中,我们可以使用[]

1
2
3
4
5
6
> (x1 <- listobj[2])
$A
[,1] [,2] [,3]
[1,] 9 0 0
[2,] 0 2 0
[3,] 0 0 1

注意,使用 [] 得到的结果是一个列表,其中包含原始列表的第二个元素。如果想要直接访问并提取出这个元素,而不是得到一个子列表,可以使用 [[]]

1
2
3
4
5
> (x2 <- listobj[[2]])
[,1] [,2] [,3]
[1,] 9 0 0
[2,] 0 2 0
[3,] 0 0 1

可以用 class() 来看看类型:

1
2
3
4
> class(x1)
[1] "list"
> class(x2)
[1] "matrix" "array"

可以通过 [[...]]$ 来访问 List 中的元素。

1
2
3
4
5
> my_list <- list(item1=1, item2="hello", item3=c(1, 2, 3))
> my_list[[1]] # 返回 1
[1] 1
> my_list$item2 # 返回 "hello"
[1] "hello"

这里补充一下,对于 data.frame 来说,也可以使用 [][[]]

见例子:

1
2
3
4
5
6
7
8
9
10
11
> dfr <- data.frame(x = c(5, 2, 7, 4),
+ y = c(TRUE, FALSE, FALSE, TRUE),
+ z = factor(c("A", "B", "A", "B")))
> dfr[2]
y
1 TRUE
2 FALSE
3 FALSE
4 TRUE
> dfr[[2]]
[1] TRUE FALSE FALSE TRUE

我们还可以通过为每个维度提供索引向量来提取列和行。那么当 drop=FALSE 时,得到的对象是一个向量,类似于从矩阵中提取行和列。

1
2
> dfr[,2]
[1] TRUE FALSE FALSE TRUE