R语言笔记之数据类型4-矩阵

矩阵

矩阵定义

矩阵是一个二维数组,只是每个元素都拥有相同的模式(数值型、字符型或逻辑型)。可通过函数matrix()创建矩阵。一般使用格式为:

1
2
3
myymatrix <- matrix(vector, nrow=number_of_rows, ncol=number_of_columns,
byrow=logical_value, dimnames=list(
char_vector_rownames, char_vector_colnames))

其中:

  • vector包含了矩阵的元素;
  • nrow和ncol用以指定行和列的维数;
  • dimnames包含了可选的、以字符型向量表示的行名和列名。
  • 选项 byrow 则表明矩阵应当按行填充( byrow=TRUE )还是按列填充( byrow=FALSE ),默认情况下按列填充。

创建矩阵

matrix()

此函数在默认情况下是按列进行填充,如下所示:

1
2
3
4
a <- 1:12
a
matrix(a, nrow=4, ncol=3) # 默认按列填充
matrix(a, nrow=3, ncol=3, byrow=T) # 按行填充

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> a <- 1:12
> a
[1] 1 2 3 4 5 6 7 8 9 10 11 12
> matrix(a, nrow=4, ncol=3) # 默认按列填充
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> matrix(a, nrow=3, ncol=3, byrow=T) # 按行填充
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9

dim()

通过dim来创建,先生成向量x,接着给向量x适当的维数,此例子中给向量的维数为5行,3列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> x <- 1:15
> x # 建立x
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
> x <- 1:15
> x # 建立x
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
> dim(x) #查看x的维度
NULL
> dim(x) <- c(5,3) # 将向量x转化为5行3列的矩阵
> x
[,1] [,2] [,3]
[1,] 1 6 11
[2,] 2 7 12
[3,] 3 8 13
[4,] 4 9 14
[5,] 5 10 15

矩阵命名

用法:Dimnames(Row_name,Col_name),给定行和列的名称,如果不需要给行或者列命名,则以NULL代替。例如:给下面的矩阵列命令:

1
2
3
4
5
6
7
a<-c(1,2,3,4,5,6);a
## [1] 1 2 3 4 5 6
a<-matrix(a,nrow=2,byrow=T,dimnames=list(c('a','b'),c('A','B','C')));a
## A B C
## a 1 2 3
## b 4 5 6

用rownames与colnames实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
b<-c(2,3,4,5,6,7) # 建立向量b
b
## [1] 2 3 4 5 6 7
b<-matrix(b,nrow=2) # 将向量b转化为矩阵
b
## [,1] [,2] [,3]
## [1,]2 4 6
## [2,]3 5 7
rownames(b)<-c("row_1","row_2") # 将矩阵行命名
colnames(b)<-c("col_1","col_2","col_3") # 将矩阵的列命名
b
## col_1 col_2 col_3
## row_12 4 6
## row_23 5 7

查看矩阵

查看矩阵的列/行相关信息

1
2
3
4
5
colnames(a) # 查看矩阵列名
## [1] "A" "B" "C"
rownames(a) # 查看矩阵行名
## [1] "a" "b"

查看矩阵的维度

1
2
3
4
5
6
7
8
dim(a) # 返回行与列数
## [1] 2 3
nrow(a) # 返回行数
## [1] 2
ncol(a) # 返回列数
## [1] 3

条件提取子矩阵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
a # 查看矩阵a
## A B C
## a 1 2 3
## b 4 5 6
a[2,3] #取矩阵a的第2列,第3个元素
## [1] 6
a[,1] #取矩阵a的第1列
## a b
## 1 4
a[1,] # 取矩阵a的第1行
## A B C
## 1 2 3
c<-a[a[,2]>4] # 取矩阵a第2行并且大于4的元素,并将其赋值给c
c
## [1] 4 5 6
x<-c(1,2,3,4,5,6,7,8,8)
x<-matrix(x,nrow=3)
x
## [,1] [,2] [,3]
## [1,]1 4 7
## [2,]2 5 8
## [3,]3 6 8
x[,3] # 选取矩阵的第3列
## [1] 7 8 8
x[3,] # 选取矩阵的第3行
## [1] 3 6 8
y<-x[,3,drop=FALSE] # 选取x矩阵的第3列,并返回一个矩阵给y
y
## [,1]
## [1,] 7
## [2,] 8
## [3,] 8
x[,-1] # 不显示矩阵的第1列
## [,1] [,2]
## [1,]4 7
## [2,]5 8
## [3,]6 8
x[-1,] # 不显示矩阵的第1行
## [,1] [,2] [,3]
## [1,]2 5 8
## [2,]3 6 8
x[,-(1:2)] # 不显示矩阵的第1,2列
## [1] 7 8 8
z<-x[,-(1:2),drop=FALSE] #不显示矩阵x的第1,2列,并且返回为一矩阵y
z
## [,1]
## [1,] 7
## [2,] 8
## [3,] 8

提取矩阵的行或列

nrowncol函数: nrow与ncol函数返回行或列的某一个数字。NCOL与NROW用于向量,即把向量作为单行的矩阵处理。 用法: nrow(x) ncol(x) NCOL(x) NROW(x) 参数: x:向量,或数据框; 值:长度为1或无的整数: 类似的有dim函数,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
ma <- matrix(1:12, 3, 4);ma # 建矩阵3行4列的矩阵
## [,1] [,2] [,3] [,4]
## [1,]1 4 710
## [2,]2 5 811
## [3,]3 6 912
nrow(ma) # 行数为3
## [1] 3
ncol(ma) # 列数为4
## [1] 4
y <-array(1:24, dim = 2:4);y # 建2行4列的数组
## , , 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
ncol(y)
## [1] 3
NCOL(1:12) # NCOL把数组作为单行的矩阵处理
## [1] 1
NROW(1:12) # 12
## [1] 12

矩阵的运算

矩阵相乘%*%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
a
## A B C
## a 1 2 3
## b 4 5 6
d <- c(1:6)
d <- matrix(d,nrow=3)
d
## [,1] [,2]
## [1,]1 4
## [2,]2 5
## [3,]3 6
e<-a%*%d
e
## [,1] [,2]
## a 14 32
## b 32 77

只有当矩阵a的列数与矩阵b的行数相等时a×b才有意义。一个m×n的矩阵a(m,n)左乘一个n×p的矩阵b(n,p),会得到一个m×p的矩阵c(m,p),满足矩阵乘法满足结合律,但不满足交换律。 运算的法则: 矩阵a的第1行的3个元素(1,2,3)分别与矩阵b第1列的3个元素(1,2,3)相乘,其和为结果为e[1,1],即e[1,1]=1×1+2×2+3×3=14; 矩阵a的第1行的3个元素(1,2,3)分别与矩阵b第2列的3个元素(4,5,6)相乘1×4+2×5+3×6=32,得到e[1,2]; 矩阵a的第2行的3个元素(4,5,6)分别与矩阵b第1列的3个元素(1,2,3)相乘4×1+5×2+6×3=32,得到e[2,1]; 矩阵a的第2行的3个元素(4,5,6)分别与矩阵b第2列的3个元素(4,5,6)相乘4×4+5×5+6×6=77,得到e[2,2].

矩阵合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
m1<-matrix(1,nrow=2,ncol=2)
m1 # 建立矩阵m1,2行2列,值为1
## [,1] [,2]
## [1,]1 1
## [2,]1 1
m2<-matrix(2,nrow=2,ncol=2)
m2 # 建立矩阵m2,2行2列,值为2
## [,1] [,2]
## [1,]2 2
## [2,]2 2
m_rbind<-rbind(m1,m2);m_rbind # 对两个矩阵m1,m2进行行合并,即上下合并
## [,1] [,2]
## [1,]1 1
## [2,]1 1
## [3,]2 2
## [4,]2 2
m_cbind<-cbind(m1,m2);m_cbind #对两个矩阵m1,m2进行列合并,即左右合并
## [,1] [,2] [,3] [,4]
## [1,]1 1 22
## [2,]1 1 22

星号表示相乘

把两个矩阵中每个对应的元素相乘,例子中a与b拥有相同的维度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a
## A B C
## a 1 2 3
## b 4 5 6
b
## col_1 col_2 col_3
## row_12 4 6
## row_23 5 7
result<-a*b #将矩阵a与矩阵b相乘,并将其结果给result
result
## AB C
## a 2 8 18
## b 12 25 42

如果维度不同,如下所示:

1
2
3
4
5
6
7
8
9
10
a
## A B C
## a 1 2 3
## b 4 5 6
c
## [1] 4 5 6
a*c # a矩阵中的每一列与c的每一行相乘,循环c
## AB C
## a 4 12 15
## b 20 20 36

增加行与列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
f<-matrix(,4,2) # 建立4行2列的空矩阵f
f
## [,1] [,2]
## [1,]NA NA
## [2,]NA NA
## [3,]NA NA
## [4,]NA NA
f[c(1,3),]<-matrix(c(1,2,3,4)) #取f的1行与3行,将向量(1,2,3,4)填充进去,默认按列填充
f
## [,1] [,2]
## [1,]1 3
## [2,]NA NA
## [3,]2 4
## [4,]NA NA
g<-matrix(,4,2)
g
## [,1] [,2]
## [1,]NA NA
## [2,]NA NA
## [3,]NA NA
## [4,]NA NA
g[c(1,3),]<-matrix(c(1,2,3,4),byrow=FALSE) # byrow=FALSE则按行填充
g
## [,1] [,2]
## [1,]1 3
## [2,]NA NA
## [3,]2 4
## [4,]NA NA

矩阵转置t()

1
2
3
4
5
6
7
8
9
10
11
12
13
f
## [,1] [,2]
## [1,]1 3
## [2,]NA NA
## [3,]2 4
## [4,]NA NA
h<-t(f)
h
## [,1] [,2] [,3] [,4]
## [1,]1 NA 2NA
## [2,]3 NA 4NA

取对角元素diag()

若要取一个方阵的对角元素,对一个向量应用diag()函数将产生以这个向量为对角元素的对角矩阵,对一个正整数k应用diag()函数将产生k维单位矩阵,如下所示:

1
2
3
4
5
6
7
8
9
10
j<-c(1,2,3,4,5,6,7,8,9)
j<-matrix(j,nrow=3)
j_diag<-diag(j) #取对角
j_diag
diag(diag(j_diag))
diag(3)
A <- matrix(1:16,nrow=4,ncol=4)
diag(A)
diag(3)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> j_diag
[1] 1 5 9
> diag(diag(j_diag))
[1] 1 5 9
> diag(3)
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1
> A <- matrix(1:16,nrow=4,ncol=4)
> diag(A)
[1] 1 6 11 16
> diag(3)
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1

求各行与列的总和与均值rowSum()rowMeans()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
j
## [,1] [,2] [,3]
## [1,]1 4 7
## [2,]2 5 8
## [3,]3 6 9
rowSums(j) # 求各行的总和
## [1] 12 15 18
rowMeans(j) # 求行的均值
## [1] 4 5 6
colSums(j) #求各列的总和
## [1] 6 15 24
colMeans(j) #求各列的均值
## [1] 2 5 8

矩阵的特征值与特征向量eigen()

矩阵A的谱分解为A=UΛU,其中Λ是由A的特征值组成的对角矩阵,U的列为A的特征值对应的特征向量,在R中可以使用eigen()得到U和A,eigen(x,symmertic, only.values=FALSE,EISPACK=FALSE),其中参数symmetric项是逻辑值,是F或T,它用于指定矩阵x是否为对称矩阵,如果不指定,系统将自动检验x是否为对称矩阵,如下所示:

1
2
3
4
5
6
7
8
9
10
> eigen(j)
eigen() decomposition
$values
[1] 1.611684e+01 -1.116844e+00 -5.700691e-16
$vectors
[,1] [,2] [,3]
[1,] -0.4645473 -0.8829060 0.4082483
[2,] -0.5707955 -0.2395204 -0.8164966
[3,] -0.6770438 0.4038651 0.4082483

矩阵的求逆solve()

矩阵求逆可用函数solve(),应用sovle(A,b)运算结果可以解线性方程组Ax=b,若b缺少,则系统默认为单位矩阵,因此可以用其进行矩阵求逆,如下所示:

1
2
A <- matrix(rnorm(16),4,4);A
solve(A)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
> A <- matrix(rnorm(16),4,4);A
[,1] [,2] [,3] [,4]
[1,] 0.3981 1.4330 0.56972 0.6897
[2,] -0.6120 1.9804 -0.13505 0.0280
[3,] 0.3411 -0.3672 2.40162 -0.7433
[4,] -1.1294 -1.0441 -0.03924 0.1888
> solve(A)
[,1] [,2] [,3] [,4]
[1,] 0.12130 -0.4308 -0.063267 -0.6283
[2,] 0.04397 0.3764 0.007696 -0.1862
[3,] 0.30921 -0.0369 0.344768 0.2331
[4,] 1.03306 -0.5029 -0.264247 0.5569

矩阵的特征值与特征向量eigen()

矩阵A的谱分解为$A=U\Lambda U’$,其中$\Lambda$是由$A$的特征值组成的对角矩阵,$U$的列为$A$的特征值对应的特征向量,在R中可以使用eigen()得到$U$和$A$,此函数参数如下所示:

1
eigen(x,symmetric,only.values=FALSE, EISPACK=FALSE)

其中,x为矩阵,symmetric项指定矩阵x是否为对称矩阵,若不指定,系统将自动检测x是否为对称矩阵,如下所示:

1
2
3
4
A <- diag(4) +1
A.e <- eigen(A, symmetric=T)
A.e
A.e$vectors%*%diag(A.e$values)%*%t(A.e$vectors)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> A <- diag(4) +1
> A.e <- eigen(A, symmetric=T)
> A.e
eigen() decomposition
$values
[1] 5 1 1 1
$vectors
[,1] [,2] [,3] [,4]
[1,] -0.5 0.8660 0.0000 0.0000
[2,] -0.5 -0.2887 -0.5774 -0.5774
[3,] -0.5 -0.2887 -0.2113 0.7887
[4,] -0.5 -0.2887 0.7887 -0.2113
> A.e$vectors%*%diag(A.e$values)%*%t(A.e$vectors)
[,1] [,2] [,3] [,4]
[1,] 2 1 1 1
[2,] 1 2 1 1
[3,] 1 1 2 1
[4,] 1 1 1 2

矩阵的Choleskey分解

对于正定矩阵A,可对其进行Choleskey分解,即$A=P’P$,其中$P$为上三角矩阵,在R中可以用函数chol()进行Choleskey分解,如下所示:

1
2
3
A <- diag(4) +1
A.c <-chol(A);A.c
t(A.c)%*%A.c

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
> A <- diag(4) +1
> A.c <-chol(A);A.c
[,1] [,2] [,3] [,4]
[1,] 1.414 0.7071 0.7071 0.7071
[2,] 0.000 1.2247 0.4082 0.4082
[3,] 0.000 0.0000 1.1547 0.2887
[4,] 0.000 0.0000 0.0000 1.1180
> t(A.c)%*%A.c
[,1] [,2] [,3] [,4]
[1,] 2 1 1 1
[2,] 1 2 1 1
[3,] 1 1 2 1
[4,] 1 1 1 2

矩阵奇异值分解svd()

A为$m \times n$矩阵,$rank(A)=r$,可以分解为$A=UDV^T$,其中,$U’U=V’V=I$。在R中可以使用函数svd()进行奇异值分解,如下所示:

1
2
3
A <- matrix(1:18, 3,6);A
A.s <- svd(A);A.s
A.s$u%*%diag(A.s$d)%*%t(A.s$v)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
> A <- matrix(1:18, 3,6);A
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 4 7 10 13 16
[2,] 2 5 8 11 14 17
[3,] 3 6 9 12 15 18
> A.s <- svd(A);A.s
$d
[1] 4.589e+01 1.641e+00 1.367e-15
$u
[,1] [,2] [,3]
[1,] -0.5290 0.7439 0.4082
[2,] -0.5761 0.0384 -0.8165
[3,] -0.6231 -0.6671 0.4082
$v
[,1] [,2] [,3]
[1,] -0.07736 -0.7196 -0.40767
[2,] -0.19033 -0.5089 0.57456
[3,] -0.30330 -0.2983 -0.02801
[4,] -0.41627 -0.0876 0.22266
[5,] -0.52924 0.1231 -0.62121
[6,] -0.64221 0.3337 0.25966
> A.s$u%*%diag(A.s$d)%*%t(A.s$v)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 4 7 10 13 16
[2,] 2 5 8 11 14 17
[3,] 3 6 9 12 15 18

矩阵QR分解qr()

A为$m \times n$矩阵时可以进行QR分解,$A=QR$,其中,$Q’Q=I$,在R中可以使用qr()进行QR分解,如下所示:

1
2
A <- matrix(1:16,4,4);A
qr(A)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
> A <- matrix(1:16,4,4);A
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> qr(A)
$qr
[,1] [,2] [,3] [,4]
[1,] -5.4772 -12.7802 -2.008e+01 -2.739e+01
[2,] 0.3651 -3.2660 -6.532e+00 -9.798e+00
[3,] 0.5477 -0.3782 1.601e-15 2.217e-15
[4,] 0.7303 -0.9125 -5.547e-01 -1.478e-15
$rank
[1] 2
$qraux
[1] 1.183e+00 1.156e+00 1.832e+00 1.478e-15
$pivot
[1] 1 2 3 4
attr(,"class")
[1] "qr"

矩阵kronecker积kronecker()

A为$m \times n$矩阵,B为$h \times k$矩阵,而A与B的kronecker积为一个$nh \times mk$维矩阵,在R中,使用函数kronecker()来过计算kronecker积,如下所示:

1
2
3
A <- matrix(1:4,2,2);A
B <- matrix(rep(1,4),2,2);B
kronecker(A,B)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> A <- matrix(1:4,2,2);A
[,1] [,2]
[1,] 1 3
[2,] 2 4
> B <- matrix(rep(1,4),2,2);B
[,1] [,2]
[1,] 1 1
[2,] 1 1
> kronecker(A,B)
[,1] [,2] [,3] [,4]
[1,] 1 1 3 3
[2,] 1 1 3 3
[3,] 2 2 4 4
[4,] 2 2 4 4

行列式计算det()

在矩阵中,计算行列式的值可以使用函数det(),如下所示:

1
2
3
4
5
6
7
8
9
10
A <- matrix(1:16,4)
B <- A
C <- matrix(1:4,2)
B[row(A) < col(A)] =0 # 构建一个新矩阵
A
B
C
det(A)
det(B)
det(C)

计算结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
> A <- matrix(1:16,4)
> B <- A
> C <- matrix(1:4,2)
> B[row(A) < col(A)] =0 # 构建一个新矩阵
> A
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> B
[,1] [,2] [,3] [,4]
[1,] 1 0 0 0
[2,] 2 6 0 0
[3,] 3 7 11 0
[4,] 4 8 12 16
> C
[,1] [,2]
[1,] 1 3
[2,] 2 4
> det(A)
[1] 0
> det(B)
[1] 1056
> det(C)
[1] -2

参考资料

  1. 多元统计分析及R语言建模(第4版) [Multivariate Statistical Analysis and Modeling for R Language] .王斌会 著
  2. R数据分析之方法与案例详解.方匡南,朱建平,姜叶飞.电子工业出版社