2.5 数组 (array)和矩阵 (matrix)简介
向量是一维的数据。数组是多维的数据。矩阵是二维的数据,因此矩阵是数组的一种特殊情况。
Dataframe不是矩阵(虽然都是方的,且取子集方法和矩阵有近似之处。 矩阵是二维的,仅包含一种数据类型的数组。 Dataframe是一个二维的列表,不同列(即列表的分量)可以存储不同的数据类型。
本质上,矩阵和数组都是以向量的形式存储的。它们只是额外地拥有dim
(即“dimensions”,维度)属性。我们可以用dim()
函数从向量创建数组/矩阵:
A <- 1:48
dim(A) <- c(6,8)
A
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] 1 7 13 19 25 31 37 43
#> [2,] 2 8 14 20 26 32 38 44
#> [3,] 3 9 15 21 27 33 39 45
#> [4,] 4 10 16 22 28 34 40 46
#> [5,] 5 11 17 23 29 35 41 47
#> [6,] 6 12 18 24 30 36 42 48
可以看到我们创建了一个二维的数组, 即一个4行6列的矩阵。
is.array(A)
#> [1] TRUE
is.matrix(A)
#> [1] TRUE
它多出来的dim
属性可以用attr()
(即“attributes”,属性)函数来查看:
attributes(A)
#> $dim
#> [1] 6 8
注意24个数字排列的方式。第一个维度是行,所以先把4行排满,随后再使用下一个维度(列),使用第2列继续排4行,就像数字一样,(十进制中)先把个位从零数到9,再使用第二个位数(十位),以此类推。下面三维和四维的例子可能会更清晰。
同时注意最左边和最上边的[1,]
, [,3]
之类的标记。你应该猜出来了,这些是索引. 假设你要抓取第五行第三列的数值:
A[5,3]
#> [1] 17
或者第三行的全部数值:
A[3,]
#> [1] 3 9 15 21 27 33 39 45
或者第四列的全部数值:
A[,4]
#> [1] 19 20 21 22 23 24
接下来我们再看一个三维的例子(还是用1-48):
dim(A) <- c(2,8,3)
A
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] 1 3 5 7 9 11 13 15
#> [2,] 2 4 6 8 10 12 14 16
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] 17 19 21 23 25 27 29 31
#> [2,] 18 20 22 24 26 28 30 32
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] 33 35 37 39 41 43 45 47
#> [2,] 34 36 38 40 42 44 46 48
它生成了三个二维的矩阵。在每个2*8的矩阵存储满16个元素后,第三个维度就要加一了。每个矩阵开头的, , x
正是第三个维度的值。同理,我们可以生成四维的数组(这是另外一种改变维度的方法。dim
作为一个属性 (attribute), 可以通过attr()
函数赋值。attr()
还可以赋值其他的属性。):
attr(A, "dim") <- c(3,4,2,2)
A
#> , , 1, 1
#>
#> [,1] [,2] [,3] [,4]
#> [1,] 1 4 7 10
#> [2,] 2 5 8 11
#> [3,] 3 6 9 12
#>
#> , , 2, 1
#>
#> [,1] [,2] [,3] [,4]
#> [1,] 13 16 19 22
#> [2,] 14 17 20 23
#> [3,] 15 18 21 24
#>
#> , , 1, 2
#>
#> [,1] [,2] [,3] [,4]
#> [1,] 25 28 31 34
#> [2,] 26 29 32 35
#> [3,] 27 30 33 36
#>
#> , , 2, 2
#>
#> [,1] [,2] [,3] [,4]
#> [1,] 37 40 43 46
#> [2,] 38 41 44 47
#> [3,] 39 42 45 48
观察每个矩阵开头的, , x, y
. x
是第三个维度,y
是第四个维度。每个二位矩阵存满后,第三个维度(x
)加一。x
达到上限后,第四个维度(y
)再加1。
类似二维矩阵,你可以通过索引任意抓取数据,比如:
A[ ,3 , , ] #每个矩阵第3列的数据,即所有第二个维度为3的数值
#> , , 1
#>
#> [,1] [,2]
#> [1,] 7 19
#> [2,] 8 20
#> [3,] 9 21
#>
#> , , 2
#>
#> [,1] [,2]
#> [1,] 31 43
#> [2,] 32 44
#> [3,] 33 45
2.5.1 给矩阵和列表的维度命名
假设我们记录了3种药物(chloroquine, artemisinin, doxycycline) 对5种疟原虫(P. falciparum, P. malariae, P. ovale, P. vivax, P. knowlesi)的疗效,其中每个药物对每种疟原虫做6次实验(这里用的是随机生成的数字)。为了记录数据,我们可以做3个65的矩阵,即一个65*3的数组。
B <- runif(90, 0, 1) #从均匀分布中取90个0到1之间的数
dim(B) <- c(6, 5, 3) #注意顺序
B
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0.6922 0.898 0.5718 0.823 0.628
#> [2,] 0.1419 0.473 0.0593 0.731 0.330
#> [3,] 0.0484 0.269 0.4750 0.257 0.922
#> [4,] 0.8174 0.699 0.6339 0.736 0.890
#> [5,] 0.8560 0.435 0.8243 0.445 0.147
#> [6,] 0.7077 0.620 0.7473 0.230 0.341
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0.116 0.960 0.8193 0.384 0.630
#> [2,] 0.260 0.782 0.5709 0.757 0.434
#> [3,] 0.495 0.826 0.5751 0.502 0.913
#> [4,] 0.118 0.424 0.0476 0.538 0.216
#> [5,] 0.157 0.914 0.2195 0.258 0.143
#> [6,] 0.396 0.750 0.5379 0.632 0.121
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0.0553 0.590 0.3285 0.726 0.4570
#> [2,] 0.6060 0.419 0.6630 0.391 0.3829
#> [3,] 0.3775 0.112 0.3821 0.813 0.3539
#> [4,] 0.1749 0.669 0.0608 0.669 0.0801
#> [5,] 0.2252 0.717 0.2401 0.095 0.4790
#> [6,] 0.9461 0.111 0.7775 0.974 0.8369
然后我们用dimnames()
(“维度名”)来命名:
dimnames(B) <- list(paste("trial.", 1:6), # 第一个维度
c('P. falciparum', 'P. malariae', 'P. ovale', 'P. vivax', 'P. knowlesi'), # 第二个维度
c('chloroquine', 'artemisinin', 'doxycycline')) # 第三个维度
B
#> , , chloroquine
#>
#> P. falciparum P. malariae P. ovale P. vivax P. knowlesi
#> trial. 1 0.6922 0.898 0.5718 0.823 0.628
#> trial. 2 0.1419 0.473 0.0593 0.731 0.330
#> trial. 3 0.0484 0.269 0.4750 0.257 0.922
#> trial. 4 0.8174 0.699 0.6339 0.736 0.890
#> trial. 5 0.8560 0.435 0.8243 0.445 0.147
#> trial. 6 0.7077 0.620 0.7473 0.230 0.341
#>
#> , , artemisinin
#>
#> P. falciparum P. malariae P. ovale P. vivax P. knowlesi
#> trial. 1 0.116 0.960 0.8193 0.384 0.630
#> trial. 2 0.260 0.782 0.5709 0.757 0.434
#> trial. 3 0.495 0.826 0.5751 0.502 0.913
#> trial. 4 0.118 0.424 0.0476 0.538 0.216
#> trial. 5 0.157 0.914 0.2195 0.258 0.143
#> trial. 6 0.396 0.750 0.5379 0.632 0.121
#>
#> , , doxycycline
#>
#> P. falciparum P. malariae P. ovale P. vivax P. knowlesi
#> trial. 1 0.0553 0.590 0.3285 0.726 0.4570
#> trial. 2 0.6060 0.419 0.6630 0.391 0.3829
#> trial. 3 0.3775 0.112 0.3821 0.813 0.3539
#> trial. 4 0.1749 0.669 0.0608 0.669 0.0801
#> trial. 5 0.2252 0.717 0.2401 0.095 0.4790
#> trial. 6 0.9461 0.111 0.7775 0.974 0.8369