多维数组和矩阵有关函数
> # 多维数组和矩阵
> # 将向量定义成数组
> z<-1:12
> dim(z)<-c(4,3)
> z
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> # 可以看出元素是按列存放的
> # 把向量定义为一维数组
> dim(z)<-12
> z
[1] 1 2 3 4 5 6 7 8 9 10 11 12
> # 构造多维数组
> #array(data= 向量数据 ,dim=length(data),dimnames= NULL);dim 是数组各维长度
> # 默认值是原向量长度 ,dimnames 是数组维的名字,默认为空值
> x<-array(1:10,dim=c(2,5))
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
> # 数组初始化
> z<-array(0,dim=c(2,3,4))
> # 构造矩阵
> #matrix(data=NA,nrow=1,ncol=1,byrow=FALSE,dimnames=NULL)
> #data 是数据向量 ,nrow 是矩阵行数 ,ncol 是矩阵的列数 , 当 byrow=TRUE 时,生成矩阵的
> # 数据按行放置 , 默认 byrow=FALSE, 数据按列放置 ,dimnames 同上
> A<-matrix(1:15,nrow=3,ncol=5,byrow=T)
> A
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
> B<-matrix(1:15,nrow=3,byrow=T)
> B
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
> C<-matrix(1:15,ncol=5,byrow=T)
> C
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
> # 数组下标
> a<-1:24
> dim(a)<-c(2,3,4)
> a[1,1,1]
[1] 1
> a[2,1,1]
[1] 2
> a[2,1:3,2:3]
[,1] [,2]
[1,] 8 14
[2,] 10 16
[3,] 12 18
> a[1,,]
[,1] [,2] [,3] [,4]
[1,] 1 7 13 19
[2,] 3 9 15 21
[3,] 5 11 17 23
> a[]<-7 # 整体赋值
> a<-1:24
> dim(a)<-c(2,3,4)
> b<-matrix(c(1,1,1,2,2,3,1,3,4,2,1,4),ncol=3,byrow=T)
> b
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 3
[3,] 1 3 4
[4,] 2 1 4
> a[b]
[1] 1 16 23 20
> # a[b] 意思是把 a 数组的第 [1,1,1],[2,2,3],[1,3,4],[2,1,4] 共四个元素作为一个整体访问
> # 数组的四则运算
> 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
> # 数组的乘除法运算实际上是数组中对应位置元素作运算
> # 长度或形状不一样的向量或数组也可以进行四则运算,计算时短向量或数组的数据会
> # 重复使用,并尽可能保留共同的数组属性
> x1<-c(10,20)
> x2<-1:6
> x1+x2
[1] 11 22 13 24 15 26
> x3<-matrix(1:6,nrow=3)
> x1+x3
[,1] [,2]
[1,] 11 24
[2,] 22 15
[3,] 13 26
> x2<-1:5
> x1+x2
[1] 11 22 13 24 15
警告信息:
In x1 + x2 : 长的对象长度不是短的对象长度的整倍数
> # 也就是说,长对象的长度只有是段对象的长度的整数倍时才能计算
> # 矩阵的运算
> #t() 函数表示矩阵的转置
> a<-matrix(1:6,nrow=3);a
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> t(a)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
> #det() 函数可求方阵的行列式
> det(matrix(1:4,ncol=2))
[1] -2
> # 向量的内积
> x<-1:5;y<-2:6
> x%*%y
[,1]
[1,] 70
> #crossprod() 函数是内积运算函数表示交叉乘积
> # 形式为 crossprod(x,y),crossprod(x) 表示 x 与 x 的内积
> crossprod(x)
[,1]
[1,] 55
> tcrossprod(x,y)
[,1] [,2] [,3] [,4] [,5]
[1,] 2 3 4 5 6
[2,] 4 6 8 10 12
[3,] 6 9 12 15 18
[4,] 8 12 16 20 24
[5,] 10 15 20 25 30
> #tcrossprod(x,y) 表示“ x%*%t(y) ”
> # 向量的外积 ( 叉积 )
> x<-1:5;y<-2:6
> x%o%y
[,1] [,2] [,3] [,4] [,5]
[1,] 2 3 4 5 6
[2,] 4 6 8 10 12
[3,] 6 9 12 15 18
[4,] 8 12 16 20 24
[5,] 10 15 20 25 30
> #x%o%y 中间是字母 o
> #outer() 函数是外积运算函数, outer(x,y) 计算向量 x 与 y 的外积
> #outer 一般调用格式为 outer(x,y,fun="*",...), 其中 x,y 是矩阵, fun 是外积运算函数
> # 默认值是乘法运算 ,outer() 在绘制三维曲面时很有用
> # 矩阵的乘法
> # 如果矩阵 A 和 B 有相同的维数 ,A*B 表示矩阵中对应元素的乘积 ,A%*%B 表示矩阵相乘
> A<-array(1:9,dim=c(3,3))
> B<-array(9:1,dim=c(3,3))
> A*B
[,1] [,2] [,3]
[1,] 9 24 21
[2,] 16 25 16
[3,] 21 24 9
> A%*%B
[,1] [,2] [,3]
[1,] 90 54 18
[2,] 114 69 24
[3,] 138 84 30
> # 二次型就表示成 x%*%A%*%x
> #crossprod(A,B) 表示是 t(A)%*%B,tcrossprod(A,B) 表示是 A%*%t(B)
> # 对角矩阵
> #diag() 函数 , 当括号中是一个向量时 , 其表示以向量中元素为对角线元素的对角矩阵
> # 当括号中是一个矩阵时 , 其表示取矩阵对角线上元素的向量
> diag(c(1,2,3))
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 2 0
[3,] 0 0 3
> diag(array(1:9,dim=c(3,3)))
[1] 1 5 9
> # 解线性方程组和求矩阵的逆矩阵
> A<-t(array(c(1:8,10),dim=c(3,3)))
> B<-c(1,1,1)
> x<-solve(A,B);x
[1] -1.000000e+00 1.000000e+00 3.806634e-16
> solve(A)
[,1] [,2] [,3]
[1,] -0.6666667 -1.333333 1
[2,] -0.6666667 3.666667 -2
[3,] 1.0000000 -2.000000 1
> # 求解线性方程组 Ax=b, 其形式为 solve(A,b); 求矩阵 A 的逆,命令为 solve(A)
> # 求矩阵的特征值与特征向量
> # 对称矩阵 A 的特征值和特征向量用函数 eigen(A) 来求 ,$values 是特征值 ,$vectors 为特征向量
> A
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 10
> eigen(A)
$values
[1] 16.7074933 -0.9057402 0.1982469
$vectors
[,1] [,2] [,3]
[1,] -0.2235134 -0.8658458 0.2782965
[2,] -0.5039456 0.0856512 -0.8318468
[3,] -0.8343144 0.4929249 0.4801895
> # 矩阵的奇异值分解
> # 函数 svd() 是对矩阵做奇异值分解, A=UDt(V), 其中 U,V 是正交矩阵 ,D 为对角阵 , 即 A 的奇异值
> # 返回值中 $d 表示矩阵奇异值也是对角阵 D 中的对角线上元素 ,$U 和 $v 对应正交阵 U 和 V
> svd(A)
$d
[1] 17.4125052 0.8751614 0.1968665
$u
[,1] [,2] [,3]
[1,] -0.2093373 0.96438514 0.1616762
[2,] -0.5038485 0.03532145 -0.8630696
[3,] -0.8380421 -0.26213299 0.4785099
$v
[,1] [,2] [,3]
[1,] -0.4646675 -0.833286355 0.2995295
[2,] -0.5537546 0.009499485 -0.8326258
[3,] -0.6909703 0.552759994 0.4658502
> #det() 用于求矩阵行列式的值
> det(A)
[1] -3
> # 最小拟合与 QR 分解
> # 函数 lsfit() 的返回值是最小二乘拟合的结果
> x<-c(0,0.2,0.4,0.6,0.8)
> y<-c(0.9,1.9,2.8,3.3,4.2)
> lsfit.sol<-lsfit(x,y)
> lsfit.sol
$coefficients
Intercept X
1.02 4.00
$residuals
[1] -0.12 0.08 0.18 -0.12 -0.02
$intercept
[1] TRUE
$qr
$qt
[1] -5.85849810 2.52982213 0.23749843 -0.02946714 0.10356728
$qr
Intercept X
[1,] -2.2360680 -0.8944272
[2,] 0.4472136 0.6324555
[3,] 0.4472136 -0.1954395
[4,] 0.4472136 -0.5116673
[5,] 0.4472136 -0.8278950
$qraux
[1] 1.447214 1.120788
$rank
[1] 2
$pivot
[1] 1 2
$tol
[1] 1e-07
attr(,"class")
[1] "qr"
> #QR 分解
> X<-matrix(c(rep(1,5),x),ncol=2)
> Xplus<-qr(X);Xplus
$qr
[,1] [,2]
[1,] -2.2360680 -0.8944272
[2,] 0.4472136 0.6324555
[3,] 0.4472136 -0.1954395
[4,] 0.4472136 -0.5116673
[5,] 0.4472136 -0.8278950
$rank
[1] 2
$qraux
[1] 1.447214 1.120788
$pivot
[1] 1 2
attr(,"class")
[1] "qr"
> X
[,1] [,2]
[1,] 1 0.0
[2,] 1 0.2
[3,] 1 0.4
[4,] 1 0.6
[5,] 1 0.8
> #QR 分解函数 qr() 输入的设计矩阵需要加以 1 为元素的列 , 返回值是列表 ,$qr 是 QR 分解中得到的
> #R 和正交 Q 矩阵的合写形式 , 上三角为 R, 下三角为 Q,$qraux 是 Q 的附加信息 , 这两个参数结果与
> # 函数 lsfit() 得到的结果相同
> # 可用 QR 分解的结果计算最小二乘系数
> b<-qr.coef(Xplus,y);b
[1] 1.02 4.00
> # 同样 QR 分解可得到最小二乘拟合的拟合值和残差
> qr.fitted(Xplus,y)
[1] 1.02 1.82 2.62 3.42 4.22
> qr.resid(Xplus,y)
[1] -0.12 0.08 0.18 -0.12 -0.02
> # 矩阵数组运算相关函数
> #dim() 求矩阵维数 ,nrow() 求矩阵行数 ,ncol() 求矩阵列数
> A<-matrix(1:6,nrow=3)
> A
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> dim(A)
[1] 3 2
> nrow(A)
[1] 3
> ncol(A)
[1] 2
> # 矩阵的合并
> #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
> #as.vector(A) 可将矩阵转化成向量
> A
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> as.vector(A)
[1] 1 2 3 4 5 6
> # 可见它是按列转换的
> # 更改数组维名称
> X<-matrix(1:6,ncol=2,dimnames=list(c("a","b","c"),c("t","y")),byrow=T);X
t y
a 1 2
b 3 4
c 5 6
> # 可在定义矩阵后,在为“维”赋值
> A
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> dimnames(A)<-list(c("as","df","gh"),c("qw","er"))
> A
qw er
as 1 4
df 2 5
gh 3 6
> # 也可以使用 rownames(),colnames() 函数来命名
> rownames(A)<-c("mn","nh","90")
> A
qw er
mn 1 4
nh 2 5
90 3 6
> # 数组的广义转置
> # 可用 aperm(A,perm) 函数把数组 A 的各维按 perm 中指定的新次序重新排序
> A<-array(1:24,dim=c(2,3,4))
> B<-aperm(A,c(2,3,1))
> # 上例中 B[i,j,k]=A[j,k,i]
> # 对于矩阵 A,aperm(A,c(2,1)) 恰好是矩阵转置 t(A)
> #apply() 函数用于对数组中的某维进行某种运算 ( 求和 , 求均值等 )
> # 一般形式 apply(A,MARGIN,FUN,...), 其中 A 为一个数组 ,MARGIN 是固定不变的维 ,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,sum)
[1] 3 7 11