目录
1.矩阵
创建矩阵
矩阵用
matrix
函数定义,实际存储成一个向量,根据保存的行数和列数对应到矩阵的元素,存储次序为按列存储。定义如
A <- matrix(11:16, nrow=3, ncol=2); print(A)
返回:
再如:
B <- matrix(c(1,-1, 1,1), nrow=2, ncol=2, byrow=TRUE); print(B)
返回:
matrix()
函数把矩阵元素以一个向量的形式输入,用
nrow
和
ncol
规定行数和列数,向量元素填入矩阵的缺省次序是按列填入,用 byrow=TRUE
选项可以转换成按行填入。
查看矩阵的行与列数
用
nrow() 和 ncol()
函数可以访问矩阵的行数和列数,如
nrow(A)
返回:
ncol(A)
返回:
矩阵有一个 dim 属性,内容是两个元素的向量,两个元素分别为矩阵的行数和列数。dim 属性可以用 dim() 函数访问。如
attributes(A)
返回:
还有一个:
dim(A)
返回:
转置
t(A)
返回:
2.矩阵子集
用
A[1,]
取出
A
的第一行,变成一个普通向量。用
A[,1]
取出
A
的第一列,变成一个普通向量。用 A[c(1,3),1:2]
取出指定行、列对应的子矩阵。如
看整个矩阵:
A
返回:
取第一行:
A[1,]
返回:
取第一列:
A[,1]
返回:
取1到3行,1到2列:
A[c(1,3), 1:2]
返回:
3.矩阵行列命名
用
colnames()
函 数 可 以 给 矩 阵 每 列 命 名, 也 可 以 访 问 矩 阵 列 名, 用
rownames()
函数可以给矩阵每行命名,也可以访问矩阵行名。如
colnames(A) <- c('X', 'Y')
rownames(A) <- c('a', 'b', 'c')
A
返回:
4.命名后取子集
矩阵可以有一个
dimnames
属性,此属性是两个元素的列表(列表见稍后部分的介绍),两个元素分别为矩阵的行名字符型向量与列名字符型向量。如果仅有其中之一,缺失的一个取为 NULL
。
有了列名、行名后,矩阵下标可以用字符型向量,如
A[,'Y']
A['b',]
A[c('a', 'c'), 'Y']
返回:
注意在对矩阵取子集时,如果取出的子集仅有一行或仅有一列,结果就不再是矩阵而是变成了 R 向量,R 向量既不是行向量也不是列向量。如果想避免这样的规则起作用,需要在方括号下标中加选项 drop=FALSE,如
A[,1,drop=FALSE]
返回:
取出了
A
的第一列,作为列向量取出,所谓列向量实际是列数等于
1
的矩阵。如果用常量作为下标,其结果维数是确定的,不会出问题;如果用表达式作为下标,则表达式选出零个、一个、多个下标,结果维数会有不同,加 drop=FALSE 则是安全的做法。
5.逻辑下标取子集
矩阵也可以用逻辑下标取子集,比如
A
返回:
A[A[,1]>=2,'Y']
返回:
6.正整数向量的矩阵取子集
矩阵本质上是一个向量添加了
dim
属性,实际保存还是保存成一个向量,其中元素的保存次序是按列填入,所以,也可以向对一个向量取子集那样,仅用一个正整数向量的矩阵取子集。如
A
返回:
A[c(1,3,5)]
返回:
为了挑选矩阵的任意元素组成的子集而不是子矩阵,可以用一个两列的矩阵作为下标,矩阵的每行的两个元素分别指定一个元素的行号和列号。如
ind <- matrix(c(1,1, 2,2, 3,2), ncol=2, byrow=TRUE)
A
返回:
ind
返回:
A[ind]
返回:
用
c(A)
或
A[]
返回矩阵
A
的所有元素。如果要修改矩阵
A
的所有元素,可以对 A[]
赋值。
7.返回对角线向量
对矩阵
A
,
diag(A)
访问
A
的主对角线元素组成的向量
diag(A)
返回:
8.创建单位矩阵
若
x
为正整数值标量,diag(x)
返回
x
阶单位阵;若
x
为长度大于
1
的向量,
diag(x) 返回以 x
的元素为主对角线元素的对角矩阵:
![](https://i-blog.csdnimg.cn/blog_migrate/4461f0514dffa9d4221ad1d8a8159bdd.png)
9.cbind() 和 rbind() 函数
若
x
是向量,
cbind(x)
把
x
变成列向量,即列数为
1
的矩阵,
rbind(x)
把 x 变成行向量。
若
x1
,
x2
,
x3
是等长的向量,
cbind(x1, x2, x3) 把它们看成列向量并在一起组成一个矩阵。cbind() 的自变量可以同时包含向量与矩阵,向量的长度必须与矩阵行数相等。
如
cbind(c(1,2), c(3,4), c(5,6))
返回:
再如,
cbind(A, c(1,-1,10))
返回:
cbind() 的自变量中也允许有标量,这时此标量被重复使用。如
cbind(1, c(1,-1,10))
返回:
而rbind() 与cbind() 用法类似,可以等长的向量看成行向量上下摞在一起,可以是矩阵与长度等于矩阵列数的向量上下摞在一起,向量长度为 1
也可以。简单说就是这两个函数互为转置!!
如
![](https://i-blog.csdnimg.cn/blog_migrate/68e5854118e0966353d406c2ba1d0082.png)
10. 矩阵运算
10.1 四则运算
矩阵可以与标量作四则运算,结果为每个元素进行相应运算,如
A
返回:
如加法运算:
C1 <- A + 2; C1
返回:
如除法运算:
C2 <- A / 2; C2
返回:
当运算为矩阵乘以一个标量时,就是线性代数中的矩阵的数乘运算。两个同形状的矩阵进行加、减运算,即对应元素相加、相减,用 A + B
,
A - B 表示,如
C1 + C2
返回:
C1 - C2
返回:
这就是线性代数中矩阵的加、减运算。
对两个同形状的矩阵,用
*
表示两个矩阵对应元素相乘
(
注意这不是线性代数中的矩阵乘法)
,用
/
表示两个矩阵对应元素相除。如
C1 * C2
返回:
C1 / C2
返回:
10.2 矩阵乘法
用
%*%
表示矩阵乘法而不是用
*
表示,注意矩阵乘法要求左边的矩阵的列数等于右边的矩阵的行数。如
先看一下前面的A,B矩阵
A
B
返回:
然后看一下矩阵相乘并赋值给c3
C3 <- A %*% B; C3
返回:
10.3 向量与矩阵相乘
B
返回:
看一下向量(1,1)与矩阵B相乘
c(1,1) %*% B
返回:
再看一下矩阵B与向量(1,1)相乘
B %*% c(1,1)
返回:
再看一下 向量*矩阵*向量
c(1,1) %*% B %*% c(1,1)
返回:
注意:矩阵乘法总是给出矩阵结果,即使此矩阵已经退化为行向量、列向量甚至于退化为标量也是一样。如果需要,可以用 c()
函数把一个矩阵转换成按列拉直的向量。
10.4 内积
设
x
,
y
是两个向量,计算向量内积,可以用
sum(x*y)
表示。
设
A
,
B
是两个矩阵,
A
T
B
是广义的内积,也称为叉积
(crossprod)
,结果是一个矩阵,元素为 A
的每列与
B
的每列计算内积的结果。
A
T
B
在
R
中可以表示为 crossprod(A, B)
,
A
T
A
可以表示为
crossprod(A)。要注意的是,crossprod() 的结果总是矩阵,所以计算
两个向量的内积用 sum(x,y) 而不用 crossprod(x,y)。
如:
sum(A,B)
crossprod(A,B)
返回:
10.5 外积
R
向量支持外积运算,记为
%o%
,
结果为矩阵。
x %o% y
的第
i
行第
j
列元素等于 x[i]
乘以
y[j]
。如
c(1,2,3) %o% c(1, -1)
返回:
这种运算还可以推广到
x
的每一元素与
y
的每一元素进行其它的某种运算,而不限于乘积运算,可以用 outer(x,y,f)
完成,其中
f
是某种运算,或者接受两个自变量的函数。
10.6 逆矩阵与线性方程组求解
用 solve(A) 求 A 的逆矩阵,如
solve(A)
solve(B)
返回:
用
solve(A,b)
求解线性方程组
Ax
=
b
中的
x
,
如
求解线性方程组
B
返回:
solve(B, c(1,2))
返回:
10.7 apply() 函数
apply(A, 2, FUN)
把矩阵
A
的每一列分别输入到函数
FUN
中,得到对应于每一列的结果,如
D <- matrix(c(6,2,3,5,4,1), nrow=3, ncol=2); D
返回:
apply(D, 2, sum)
返回:
apply(A, 1, FUN)
把矩阵
A
的每一行分别输入到函数
FUN
中,得到与每一行对应的结果,如
apply(D, 1, mean)
返回:
如果函数
FUN
返回多个结果,则
apply(A, 2, FUN)
结果为矩阵,矩阵的每一列是输入矩阵相应列输入到 FUN
的结果,结果列数等于
A
的列数。如
apply(D, 2, range)
返回:
如果函数
FUN
返回多个结果,为了对每行计算
FUN
的结果,结果存入一个与输入的矩阵行数相同的矩阵,应该用 t(apply(A, 1, FUN))
的形式,如
t(apply(D, 1, range))
返回:
10.8 多维数组
矩阵是多维数组
(array)
的特例。矩阵是
x
ij
, i
= 1
,
2
, . . . , n, j
= 1
,
2
, . . . , m 这样的两下标数据的存贮格式,三维数组是 x
ijk
, i
= 1
,
2
, . . . , n, j
= 1,
2
, . . . , m, k
= 1
,
2
, . . . , p
这样的三下标数据的存贮格式,
s
维数组则是有
s 个下标的数据的存贮格式。实际上,给一个向量添加一个 dim
属性就可以把它 变成多维数组。
多维数组的一般定义语法为数组名 <- array( 数组元素 ,dim=c(第一下标个数, 第二下标个数 , ..., 第 s 下标个数 ))其中数组元素的填入次序是第一下标变化最快,第二下标次之,最后一个下标 是变化最慢的。这种次序称为 FORTRAN 次序。
下面是一个三维数组定义例子。
ara <- array(1:24, dim=c(2,3,4)); ara
返回:
这样的数组保存了
x
ijk
, i
= 1
,
2
, j
= 1
,
2
,
3
, k
= 1
,
2
,
3
,
4
。三维数组
ara
可以看成是 4
个
2
×
3
矩阵。取出其中一个如
ara[,,2]
(
取出第二个矩阵
)
ara[,,2]
返回:
多维数组可以利用下标进行一般的子集操作,比如
ara[,2, 2:3]
是
x
ijk
, i
= 1,
2
, j
= 2
, k
= 2
,
3
的值,结果是一个
2
×
2
矩阵
:
ara[,2,2:3]
返回:
多维数组在取子集时如果某一维下标是标量,则结果维数会减少,可以在方括号内用 drop=FALSE
选项避免这样的规则发生作用。
类似于矩阵,多维数组可以用一个矩阵作为下标,如果是三维数组,矩阵就需要有 3
列,四维数组需要用
4
列矩阵。下标矩阵的每行对应于一个数组元素。