R 中的阵列(array)是一种多维的数据结构,是对矩阵的多维扩展。 矩阵可以看作是二维的阵列。向量可以看作是一维的阵列。
阵列的维数是阵列的重要性质。使用 dim() 来获得阵列的维数。 阵列的维数是一个向量,向量的长度即为阵列的维度。 维数向量中的数均为整数,它们的顺序至关重要。
阵列的索引,可以使用[]来访问阵列中的元素或子阵列。
R中的向量,默认情况下可以理解为“列”向量,也就是当未加说明时,凡向量如果 组成矩阵,应该将其当成“列”向量。 R中的矩阵是由等长的一组向量按顺序排列而成的,输出形式上是把向量排成列, 每列为一个向量,所以也常称向量为“列”向量。 矩阵中的行向量是由每个列向量抽出指定位置的数排列成的, R中的行向量,实质上是一行多列的矩阵,而不是向量。 可以使用 class() 来测试行向量,得到 matrix 。
以一个2x3的矩阵a为例
> ( a <- array(1:6, dim=c(2,3)) )
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> class(a)
[1] "matrix"
它的维数是 c(2, 3),即它的第1维数是2,也就是说它的最基本的向量(列向量) 的长度是2;它的第2维数是3,也就是说它的2维结构是由3组向量排列而成的。 它的索引方法是[,],列向量是由最后一个索引项指明的。
也可以使用 matrix() 来创建 2x3 的矩阵,更简单
> ( a <- matrix(1:6, 2) )
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> class(a)
[1] "matrix"
3维及以上的阵列是比较复杂的。下面以3维的阵列为例:
> a <- 1:2
> b <- 2:4
> c <- 3:6
> (ab <- a %o% b)
[,1] [,2] [,3]
[1,] 2 3 4
[2,] 4 6 8
> class(ab)
[1] "matrix"
> dim(ab)
[1] 2 3
> (abc <- ab %o% c)
, , 1
[,1] [,2] [,3]
[1,] 6 9 12
[2,] 12 18 24
, , 2
[,1] [,2] [,3]
[1,] 8 12 16
[2,] 16 24 32
, , 3
[,1] [,2] [,3]
[1,] 10 15 20
[2,] 20 30 40
, , 4
[,1] [,2] [,3]
[1,] 12 18 24
[2,] 24 36 48
> class(abc)
[1] "array"
> dim(abc)
[1] 2 3 4
上面的 %o% 是向量、矩阵或者阵列之间的“外积”操作,外积操作相当于对参与操 作的两个向量、矩阵或者阵列内的每个元素进行一次相乘,把相乘的结果排成一 个新的阵列,新阵列的维度是原来两个阵列的维度的拼接,新阵列中的元素个数 是原来两个阵列的元素个数的乘积。 需要注意的是数学中存在有多种向量“外积”的定义方式,在使用时注意区分。
> abc[,,1]
[,1] [,2] [,3]
[1,] 6 9 12
[2,] 12 18 24
> abc[,1,]
[,1] [,2] [,3] [,4]
[1,] 6 8 10 12
[2,] 12 16 20 24
> abc[1,,]
[,1] [,2] [,3] [,4]
[1,] 6 8 10 12
[2,] 9 12 15 18
[3,] 12 16 20 24
上面以外积的方式生成了3维的阵列abc。注意到abc的构成如下图所示:
abc的结构
可以使用 outer() 来计算两个阵列的外积。不过更加有趣的是使用任意的函数来 代替 * 可以在外积的空间里生成这个多维函数的值。例如下面在x、y的一个方形 定义域内计算了f(x,y)的值。并使用 rgl 的 persp3d() 来绘制三维曲面。
f <- function(x, y) sin(x) * sin(y)
x <- seq(0,3,length=30)
y <- x
z <- outer(x,y,f)
persp(x,y,z)
library(rgl)
open3d()
persp3d(x,y,z,col='lightblue')
rgl.postscript("persp3d.eps", "eps") # 保存图像
三维曲面
array 的转置,使用 aperm() 方法。 aperm(a, perm) 表示对多维阵列进行转置, perm向量表示需要对调转置的维。一次可以同时对多个维进行对调。例如 a 是三 维阵列,aperm(a, c(3,2,1)) 表示把 a 转置为第三维和第一维对调的情形。而矩 阵的转置使用 t() 。t() 只是 aperm() 方法的一种特殊情形。例如 A 是一个矩 阵,即二维阵列,则t(A) 相当于 aperm(A, c(2,1))。
cbind() 和 rbind() 可以用来把一组向量生成矩阵。当向量不等长时,循环复制 欠长的向量。使用 cbind() 可以把一个向量强制做成一个列向量矩阵。使用 rbind() 可以把一个向量强制做成一个行向量矩阵。