多维数组与矩阵

R

R基础知识

1 一、生成数组或矩阵

数组(array)可以看成是带多个下标的类型相同的集合,常用的是数值型的数组如矩阵(数值型二维数组),也可以有其它类型(如字符型、逻辑性、复数型)。R软件可以很容易地生成和处理数组,特别是矩阵。

数组有一个特征属性叫做维数向量(dim属性),维数向量是一个元素取正整数的向量,其长度是数组的维数,比如维数向量有两个元素时数组为二维数组(如矩阵)。维数向量的每一个元素指定了该下标的上界,下标的下界总为1.

1.1 (一)将向量定义为数组

向量可以直接看作为一个一维数组,但要将向量定义为二维以上的数组,需要定义维数向量(dim属性)。比如:

z <- 1:12
z
 [1]  1  2  3  4  5  6  7  8  9 10 11 12
dim(z) <- c(3,4)
z
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

注意:矩阵的元素是按列存放的。也可以定义为三维数组。如:

dim(z) <- c(3,2,2)
z
, , 1

     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2

     [,1] [,2]
[1,]    7   10
[2,]    8   11
[3,]    9   12

1.2 (二)用array()函数构造多维数组

R软件可以用array()函数直接构造数组,其构造形式为:

array(data=NA, dim=length(data) ,dimnames=NULL)

其中data是一个向量数据,dim是数组各维的长度,缺省时为原向量的长度。dimnames是数组维的名字,缺省时为空。如: 产生一个4*5的二维数组(矩阵),即:

x<-array(1:20,dim=c(4,5))
x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

利用该函数也可以产生三维及以上的数组,如:

x <- array(c(1,2,5,7,4,8,9,10), dim=c(2,2,2))

产生一个222的三维数组。

x
, , 1

     [,1] [,2]
[1,]    1    5
[2,]    2    7

, , 2

     [,1] [,2]
[1,]    4    9
[2,]    8   10

说明:如果数组每个元素相同,则array函数的data部分直接写成数字即可(与下面的matrix()函数类似)如:

x<-array(0,dim=c(4,5))
x
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0

产生一个4*5零矩阵。

1.3 (三)用matrix()函数构造矩阵

函数matrix()是专门用来构造矩阵(二维数组)的函数,其构造形式为

matrix(data=NA,nrow=1,ncol=1,byrow=FALSE,dimnames=NULL)

其中data是一个向量数据,nrow是矩阵的行数,ncol是矩阵的列数。当byrow=TRUE时,生成矩阵的数据按行放置,缺省时,相当于byrow=FALSE,按列放置。dimnames是数组维的名字,缺省时为空。 比如,构造一个3*5阶的矩阵

A<-matrix(1:15,nrow=3,ncol=5,byrow=TRUE)
A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10
[3,]   11   12   13   14   15

注意:下面两种方式与上述的格式是等价的。

 A<-matrix(1:15,nrow=3,byrow=TRUE)
 A<-matrix(1:15,ncol=5,byrow=TRUE)

2 二、数组的下标

要访问数组的某个元素,只要写出数组名和方括号内的用逗号分开的下标即可,或进行运算。

2.1 (一)数组的下标

a<-1:24
 dim(a)<-c(2,3,4)
 a[2,1,2]
[1] 8

要进一步还可以在每一个下标位置写一个下标向量,表示这一维取出所有指定下标的元素,如a[1,2:3,2:3]取出所有第一下标为1,第二下标为2或3,第三下标为2或3的元素,如:

a[1,2:3,2:3]
     [,1] [,2]
[1,]    9   15
[2,]   11   17

注意:因为第一维只有一个下标,所以退化了,得到一个维数向量为2*2的数组。 另外,如果略写某一维的下标,则表示该维全选,例如:

2.2 (二)不规则的数组下标

在R语言中,甚至可以把数组中的任意位置的元素作为数组访问,其方法就是用一个二维数组作为数组的下标,二维数组的每一行就是一个元素的下标,列数为数组的维数。例如要把上面的性状为3*3的矩阵A的第[1,1] [1,3] [2,1] [2,2]号元素作为一个整体访问,先定义一个包含这些下标作为行的二维数组。

b<-matrix(c(1,1,1,3,2,1,2,2),ncol=2,byrow=TRUE)
b
     [,1] [,2]
[1,]    1    1
[2,]    1    3
[3,]    2    1
[4,]    2    2
a[b]
[1] 1 1 2 2 1 3 1 2

注意:取出的是一个向量,我们还可以对这几个元素赋值,如:

a
, , 1

     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

, , 2

     [,1] [,2] [,3]
[1,]    7    9   11
[2,]    8   10   12

, , 3

     [,1] [,2] [,3]
[1,]   13   15   17
[2,]   14   16   18

, , 4

     [,1] [,2] [,3]
[1,]   19   21   23
[2,]   20   22   24
a[b]<-c(3,5,6,7)
a
, , 1

     [,1] [,2] [,3]
[1,]    6    5    5
[2,]    7    4    6

, , 2

     [,1] [,2] [,3]
[1,]    7    9   11
[2,]    8   10   12

, , 3

     [,1] [,2] [,3]
[1,]   13   15   17
[2,]   14   16   18

, , 4

     [,1] [,2] [,3]
[1,]   19   21   23
[2,]   20   22   24

3 三、数组的四则运算

3.1 (一)矩阵的乘法

可以对数组之间进行四则运算(+、-、*、/),这时进行的是数组对应元素的四则运算,参加运算的数组一般应该是相同性状的(dim属性完全相同)例如:

A<-matrix(1:6,nrow=2,byrow=T)
A
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
B<-matrix(1:6,nrow=2)
B
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
C<-matrix(c(1,2,2,3,3,4),nrow=2)
C
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    2    3    4
D<-2*C+A/B
D
     [,1]     [,2] [,3]
[1,]    3 4.666667  6.6
[2,]    6 7.250000  9.0

从这个例子可以看出,数组的加、减运算和数乘运算满足原矩阵运算的性质,但数组的乘、除法运算实际上是数组中对应位置的元素作运算。

4 四、矩阵的运算

4.1 (一)矩阵的乘法

如果矩阵A和B具有相同的维数,则AB表示矩阵中对应的元素的乘积A%%B表示通常意义下的两个矩阵的乘积(当然要求矩阵A的列数等于矩阵B的行数)。如:

A<-matrix(1:9,nrow=3)
A
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
B<-matrix(9:1,nrow=3)
B
     [,1] [,2] [,3]
[1,]    9    6    3
[2,]    8    5    2
[3,]    7    4    1
C<-A*B;C
     [,1] [,2] [,3]
[1,]    9   24   21
[2,]   16   25   16
[3,]   21   24    9
D<-A%*%B
D
     [,1] [,2] [,3]
[1,]   90   54   18
[2,]  114   69   24
[3,]  138   84   30

4.2 (二)矩阵的转置运算

对于矩阵A,函数t(A)表示矩阵A的转置,即AT 如:

A<-matrix(1:6,nrow=2)
A
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
t(A)
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6

4.3 (三)方阵的行列式

函数det()是用来求方阵行列式的值,如:

det(matrix(1:4,ncol=2))
[1] -2

4.4 (四)生成对角矩阵和对矩阵取对角运算

函数diag()依赖于它的变量,当v是一个向量时,diag(v)表示以v的元素为对角元素的对角阵。当M是一个矩阵时,则diag(M)表示的是取M对角线上的元素的向量。如:

v<-c(1,4,5)
diag(v)
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    4    0
[3,]    0    0    5
m<-matrix(1:9,nrow=3)
m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
 diag(m)
[1] 1 5 9

5 五、与矩阵运算有关的函数

5.1 (一)去矩阵的维数

函数dim(A)得到矩阵的维数,函数nrow(A)得到矩阵A的行数,函数ncol(A)得到矩阵A的列数。如:

A<-matrix(1:6,nrow=2)
A
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
dim(A)
[1] 2 3
nrow(A)
[1] 2
ncol(A)
[1] 3

5.2 (二)矩阵的合并

函数cbind()把其自变量横向拼成一个大矩阵,rbind()把其自变量纵向合拼成一个大矩阵。cbind()的自变量是矩阵或看做列向量的向量时,自变量的高度应该相等。rbind()的自变量是矩阵或看做行向量的向量时,自变量的宽度应该相等。

如果参与合并的的自变量比其变量短,则循环补足后合并。如:

x1<-rbind(c(1,2),c(3,4))
x1
     [,1] [,2]
[1,]    1    2
[2,]    3    4
x2<-10+x1
x3<-cbind(x1,x2)
x3
     [,1] [,2] [,3] [,4]
[1,]    1    2   11   12
[2,]    3    4   13   14
x4<-rbind(x1,x2)
x4
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]   11   12
[4,]   13   14
cbind(1,x1)
     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    1    3    4

5.3 (三)矩阵的拉直(把矩阵转化为向量)

设A是一个矩阵,则函数as.vector(A)可以将矩阵转化为向量,它是将矩阵A按列拉成向量。如:

A<-matrix(1:6,nrow=2)
A
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
A<-matrix(1:6,nrow=2)
A
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
as.vector(A)
[1] 1 2 3 4 5 6

5.4 (四)apply函数

对于想对矩阵的各行或各列进行某种计算,可用apply函数,其一般形式为:

apply(A,MARGIN,FUN,…)

其中A为一个矩阵(或数组),MARGIN取1,代表对行进行运算;MARGIN取2,代表队列进行运算,FUN是用来计算的函数。如:

A<-matrix(1:6,nrow=2)
A
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
 apply(A,1,sum)
[1]  9 12
apply(A,2,mean)
[1] 1.5 3.5 5.5

说明:求矩阵行列的均值还可分别用函数rowmean()和colmean()。

陈琼博士

陈 琼

博士 副主任医师

他从事肿瘤登记与人群流行病学研究,编写肿瘤登记年报,并开发和维护个人网站。他撰写博文,分享数据分析方法、可视化技巧和自动化报告解决方案,同时学习 R 语言,开发 R 包,不断探索高效的数据处理与展示方式。 🚀

回到顶部