| #2.1.3矩阵(Matrix) |
| #矩阵:一个二维数组 |
| #矩阵的每个元素都必须具有相同的数据类型 |
| ### 1.矩阵的创建与引用 ### |
| #生成一个矩阵 |
| matrix(vector,nrow=number_of_rows,ncol=number_of_columns,byrow=T/F) |
| diag() #生成一个对角矩阵 |
| #例: |
| # 生成全部是0的矩阵 |
| (zero = matrix(0, nrow = 3, ncol = 3)) |
| ## [,1] [,2] [,3] |
| ## [1,] 0 0 0 |
| ## [2,] 0 0 0 |
| ## [3,] 0 0 0 |
| # 生成一个对角全是1的矩阵,直接在diag中输入对角线向量即可 |
| (dig = diag(rep(1, 4))) |
| ## [,1] [,2] [,3] [,4] |
| ## [1,] 1 0 0 0 |
| ## [2,] 0 1 0 0 |
| ## [3,] 0 0 1 0 |
| ## [4,] 0 0 0 1 |
| #额外备注 |
| rep(x,n) #将vector x的值循环n遍 |
| #例: |
| rep(1, 4) |
| ##[1] 1 1 1 1 |
| rep(1:4, 2) |
| ##[1] 1 2 3 4 1 2 3 4 |
| #观察区别 |
| diag(1:4) |
| ## [,1] [,2] [,3] [,4] |
| ##[1,] 1 0 0 0 |
| ##[2,] 0 2 0 0 |
| ##[3,] 0 0 3 0 |
| ##[4,] 0 0 0 4 |
| diag(4) |
| ##[,1] [,2] [,3] [,4] |
| ##[1,] 1 0 0 0 |
| ##[2,] 0 1 0 0 |
| ##[3,] 0 0 1 0 |
| ##[4,] 0 0 0 1 |
| #从已有向量1:12数据转化成矩阵,如果没写byrow=T,默认将向量按列排序 |
| (M = matrix(1:12, nrow = 3, ncol = 4)) |
| ## [,1] [,2] [,3] [,4] |
| ## [1,] 1 4 7 10 |
| ## [2,] 2 5 8 11 |
| ## [3,] 3 6 9 12 |
| #以向量1:4为对角线的对角矩阵(重复例子,上面已有) |
| (N = diag(1:4)) |
| ## [,1] [,2] [,3] [,4] |
| ## [1,] 1 0 0 0 |
| ## [2,] 0 2 0 0 |
| ## [3,] 0 0 3 0 |
| ## [4,] 0 0 0 4 |
| ### 2.矩阵的常用操作 ### |
| ## (1) 矩阵概览 ## |
| # 查看矩阵的维度/行列数 |
| dim(M) |
| ## [1] 3 4 |
| # 提取矩阵的行数 |
| nrow(M) |
| ## [1] 3 |
| # 提取矩阵的列数 |
| ncol(M) |
| ## [1] 4 |
| # 引用元素 |
| M[1, 2] |
| ## [1] 4 |
| M[1:2, 2:3] |
| ## [,1] [,2] |
| ## [1,] 4 7 |
| ## [2,] 5 8 |
| # 给行列命名 |
| colnames(M) = paste0("x_", 1:4) |
| rownames(M) = (letters[1:3]) |
| M |
| ## x_1 x_2 x_3 x_4 |
| ##a 1 4 7 10 |
| ##b 2 5 8 11 |
| ##c 3 6 9 12 |
| colnames(M) = 1:4 |
| rownames(M) = c("一","二","三") |
| M |
| ## 1 2 3 4 |
| ##一 1 4 7 10 |
| ##二 2 5 8 11 |
| ##三 3 6 9 12 |
| colnames(M) = paste0("x_", 1:4) |
| rownames(M) = 1:3; M |
| ## x_1 x_2 x_3 x_4 |
| ## 1 1 4 7 10 |
| ## 2 2 5 8 11 |
| ## 3 3 6 9 12 |
| # 同样的命令可调用行列名 |
| colnames(M) |
| ## [1] "x_1" "x_2" "x_3" "x_4" |
| rownames(M) |
| ## [1] "1" "2" "3" |
| ## (2) 将多个矩阵合并 ## |
| cbind() #按列合并 |
| rbind() #按行合并 |
| #例: |
| (A = matrix(1:9, nrow = 3, ncol = 3, byrow = T)) |
| ## [,1] [,2] [,3] |
| ## [1,] 1 2 3 |
| ## [2,] 4 5 6 |
| ## [3,] 7 8 9 |
| (B = diag(11:13)) |
| ## [,1] [,2] [,3] |
| ## [1,] 11 0 0 |
| ## [2,] 0 12 0 |
| ## [3,] 0 0 13 |
| rbind(A, B) |
| ## [,1] [,2] [,3] |
| ## [1,] 1 2 3 |
| ## [2,] 4 5 6 |
| ## [3,] 7 8 9 |
| ## [4,] 11 0 0 |
| ## [5,] 0 12 0 |
| ## [6,] 0 0 13 |
| cbind(A, B) |
| ## [,1] [,2] [,3] [,4] [,5] [,6] |
| ## [1,] 1 2 3 11 0 0 |
| ## [2,] 4 5 6 0 12 0 |
| ## [3,] 7 8 9 0 0 13 |
| ### 3.矩阵的数学操作 ### |
| ## (1) 矩阵的加减乘运算 ## |
| A + B |
| ## [,1] [,2] [,3] |
| ## [1,] 12 2 3 |
| ## [2,] 4 17 6 |
| ## [3,] 7 8 22 |
| A - B |
| ## [,1] [,2] [,3] |
| ## [1,] -10 2 3 |
| ## [2,] 4 -7 6 |
| ## [3,] 7 8 -4 |
| A * B #错误的!!!仅仅是各个元素对应相乘 |
| ## [,1] [,2] [,3] |
| ## [1,] 11 0 0 |
| ## [2,] 0 60 0 |
| ## [3,] 0 0 117 |
| A %*% B #矩阵的乘法,线性代数的乘法 |
| ## [,1] [,2] [,3] |
| ## [1,] 11 24 39 |
| ## [2,] 44 60 78 |
| ## [3,] 77 96 117 |
| solve() #求矩阵的逆 |
| #例: |
| hilbert <- function(n) { i <- 1:n; 1 / outer(i - 1, i, "+") } |
| h8 <- hilbert(8); h8 |
| ##[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] |
| ##[1,] 1.0000000 0.5000000 0.3333333 0.25000000 0.20000000 0.16666667 0.14285714 0.12500000 |
| ##[2,] 0.5000000 0.3333333 0.2500000 0.20000000 0.16666667 0.14285714 0.12500000 0.11111111 |
| ##[3,] 0.3333333 0.2500000 0.2000000 0.16666667 0.14285714 0.12500000 0.11111111 0.10000000 |
| ##[4,] 0.2500000 0.2000000 0.1666667 0.14285714 0.12500000 0.11111111 0.10000000 0.09090909 |
| ##[5,] 0.2000000 0.1666667 0.1428571 0.12500000 0.11111111 0.10000000 0.09090909 0.08333333 |
| ##[6,] 0.1666667 0.1428571 0.1250000 0.11111111 0.10000000 0.09090909 0.08333333 0.07692308 |
| ##[7,] 0.1428571 0.1250000 0.1111111 0.10000000 0.09090909 0.08333333 0.07692308 0.07142857 |
| ##[8,] 0.1250000 0.1111111 0.1000000 0.09090909 0.08333333 0.07692308 0.07142857 0.06666667 |
| sh8 <- solve(h8);sh8 |
| ##[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] |
| ##[1,] 64 -2016 20160 -92400 221760 -288288 192192 -51480 |
| ##[2,] -2016 84672 -952560 4656960 -11642400 15567552 -10594584 2882880 |
| ##[3,] 20160 -952560 11430720 -58212000 149688000 -204324119 141261119 -38918880 |
| ##[4,] -92400 4656960 -58212000 304919999 -800414996 1109908794 -776936155 216215998 |
| ##[5,] 221760 -11642400 149688000 -800414996 2134439987 -2996753738 2118916783 -594593995 |
| ##[6,] -288288 15567552 -204324119 1109908793 -2996753738 4249941661 -3030050996 856215352 |
| ##[7,] 192192 -10594584 141261119 -776936154 2118916782 -3030050996 2175421226 -618377753 |
| ##[8,] -51480 2882880 -38918880 216215998 -594593995 856215351 -618377753 176679358 |
| round(sh8 %*% h8, 3) |
| ##[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] |
| ##[1,] 1 0 0 0 0 0 0 0 |
| ##[2,] 0 1 0 0 0 0 0 0 |
| ##[3,] 0 0 1 0 0 0 0 0 |
| ##[4,] 0 0 0 1 0 0 0 0 |
| ##[5,] 0 0 0 0 1 0 0 0 |
| ##[6,] 0 0 0 0 0 1 0 0 |
| ##[7,] 0 0 0 0 0 0 1 0 |
| ##[8,] 0 0 0 0 0 0 0 1 |
| #矩阵的数学操作函数 |
| A+B;A-B;A*B #对矩阵的各个元素完成加减乘运算 |
| A%*%B #矩阵乘法 |
| crossprod(A,B) #矩阵A的转置与矩阵B的乘法 |
| tcrossprod(A,B) #矩阵A与矩阵B的转置的乘法 |
| t(A) #求矩阵A的转置 |
| solve(A) #求矩阵A的逆 |
| eigen(A) #对矩阵进行特征值分解,结果输出特征值及特征向量 |
| svd(A) #对矩阵进行svd奇异值分解,结果可输出矩阵A的奇异值及两个正交阵U,V |
| #例: |
| # 矩阵的转置、求逆及分解 |
| #原型: |
| (A = matrix(1:9, nrow = 3, ncol = 3, byrow = T)) |
| ##[,1] [,2] [,3] |
| ##[1,] 1 2 3 |
| ##[2,] 4 5 6 |
| ##[3,] 7 8 9 |
| (B = diag(11:13)) |
| ##[,1] [,2] [,3] |
| ##[1,] 11 0 0 |
| ##[2,] 0 12 0 |
| ##[3,] 0 0 13 |
| #求: |
| solve(B) # 求矩阵逆 |
| ## [,1] [,2] [,3] |
| ## [1,] 0.09090909 0.00000000 0.00000000 |
| ## [2,] 0.00000000 0.08333333 0.00000000 |
| ## [3,] 0.00000000 0.00000000 0.07692308 |
| t(A) # 求矩阵转置 |
| ## [,1] [,2] [,3] |
| ## [1,] 1 4 7 |
| ## [2,] 2 5 8 |
| ## [3,] 3 6 9 |
| eigen(A) # 特征值分解 |
| ## eigen() decomposition |
| ## $values |
| ## [1] 1.611684e+01 -1.116844e+00 -1.303678e-15 |
| ## |
| ## $vectors |
| ## [,1] [,2] [,3] |
| ## [1,] -0.2319707 -0.78583024 0.4082483 |
| ## [2,] -0.5253221 -0.08675134 -0.8164966 |
| ## [3,] -0.8186735 0.61232756 0.4082483 |
| svd(A) # 奇异值svd分解 |
| ## $d |
| ## [1] 1.684810e+01 1.068370e+00 4.418425e-16 |
| ## |
| ## $u |
| ## [,1] [,2] [,3] |
| ## [1,] -0.2148372 0.8872307 0.4082483 |
| ## [2,] -0.5205874 0.2496440 -0.8164966 |
| ## [3,] -0.8263375 -0.3879428 0.4082483 |
| ## |
| ## $v |
| ## [,1] [,2] [,3] |
| ## [1,] -0.4796712 -0.77669099 -0.4082483 |
| ## [2,] -0.5723678 -0.07568647 0.8164966 |
| ## [3,] -0.6650644 0.62531805 -0.4082483 |
| ## (2) rARPACK的应用 ## |
| # 打开这个包 |
| # install.packages("rARPACK") |
| library(rARPACK) #rARPACK包主要针对大规模矩阵运算 |
| eigs() #进行特征值分解 |
| svds() #进行SVD分解 |
| # 构造一个1000维的大型矩阵 |
| T = matrix(1:1000000, 1000, 1000) |
| # 正常分解与快速分解的对比,此处以选择前5个特征(奇异)值为例 |
| system.time(svd(T)) |
| ## 用户 系统 流逝 |
| ## 2.07 0.00 2.08 |
| system.time(svds(T, 5)) |
| ## 用户 系统 流逝 |
| ## 0.06 0.00 0.08 |
| system.time(eigen(T)) |
| ## 用户 系统 流逝 |
| ## 4.33 0.02 4.35 |
| system.time(eigs(T, 5)) |
| ## 用户 系统 流逝 |
| ## 0.12 0.00 0.12 |
| #额外备注:system.time()统计一个程序运行时间的函数 |
| #如果里面用的是一个程序,那就用大括号{}括起来 |
| #例: |
| a = 1+1 |
| system.time({a = 1+1}) |
| ## 用户 系统 流逝 |
| ## 0 0 0 |
| ## (3) 稀疏矩阵 ## |
| # install.packages("Matrix") |
| library(Matrix) #Matrix包提供了很多独特的存储、处理稀疏矩阵的方法 |
| #生成稀疏矩阵的两个函数:Matrix()和spMatrix() |
| Matrix(vector,nrow=number_of_row,ncol=number_of_column,sparse = TRUE/FALSE) |
| #Matrix()和matrix()类似,区别在于需要设定参数Sparse=T或F来定于是否稀疏矩阵 |
| #假如Sparse=T,则会生成dgCMatrix稀疏矩阵类型,先将列按顺序排好再存储起来的方式存储 |
| #假如不设定该参数,则会自动数矩阵中的0的个数,超过一半就会设置为稀疏模式 |
| #例: |
| # 生成普通矩阵 |
| vector = c(1:3, rep(0, 5), 6:9) |
| (m1 = matrix(vector, nrow = 3, ncol = 4)) |
| ## [,1] [,2] [,3] [,4] |
| ## [1,] 1 0 0 7 |
| ## [2,] 2 0 0 8 |
| ## [3,] 3 0 6 9 |
| # 生成稀疏矩阵方法1 |
| (m2 = Matrix(vector, nrow = 3 ,ncol = 4, sparse = TRUE)) |
| ## 3 x 4 sparse Matrix of class "dgCMatrix" |
| ## |
| ## [1,] 1 . . 7 |
| ## [2,] 2 . . 8 |
| ## [3,] 3 . 6 9 |
| (m3 = Matrix(vector, nrow = 3 ,ncol = 4, sparse = FALSE)) |
| ## 3 x 4 Matrix of class "dgeMatrix" |
| ## [,1] [,2] [,3] [,4] |
| ## [1,] 1 0 0 7 |
| ## [2,] 2 0 0 8 |
| ## [3,] 3 0 6 9 |
| spMatrix(nrow,ncol,i=integer(),j=integer(),x=numeric()) |
| #前两个参数设定矩阵的行列数,i设定需要填补数字的行号,j为列号,x就是需要填补的元素 |
| #spMatrix()函数则通过定义非0元素的行列位置来生成dgTMatrix稀疏矩阵类型 |
| #dgTMatrix稀疏矩阵类型存储方式是将非0元素所在的行、列以及它的值构成一个三元组(i,j,v),再按某种规律把它们存储起来 |
| #例: |
| # 生成稀疏矩阵方法2 |
| (m4 = spMatrix(10, 20, i = c(1, 3:8), j = c(2, 9, 6:10), x = 7 * (1:7))) |
| ## 10 x 20 sparse Matrix of class "dgTMatrix" |
| ## |
| ## [1,] . 7 . . . . . . . . . . . . . . . . . . |
| ## [2,] . . . . . . . . . . . . . . . . . . . . |
| ## [3,] . . . . . . . . 14 . . . . . . . . . . . |
| ## [4,] . . . . . 21 . . . . . . . . . . . . . . |
| ## [5,] . . . . . . 28 . . . . . . . . . . . . . |
| ## [6,] . . . . . . . 35 . . . . . . . . . . . . |
| ## [7,] . . . . . . . . 42 . . . . . . . . . . . |
| ## [8,] . . . . . . . . . 49 . . . . . . . . . . |
| ## [9,] . . . . . . . . . . . . . . . . . . . . |
| ## [10,] . . . . . . . . . . . . . . . . . . . . |
| summary(m4) #统一看到它填补元素的情况 |
| ## 10 x 20 sparse Matrix of class "dgTMatrix", with 7 entries |
| ## i j x |
| ## 1 1 2 7 |
| ## 2 3 9 14 |
| ## 3 4 6 21 |
| ## 4 5 7 28 |
| ## 5 6 8 35 |
| ## 6 7 9 42 |
| ## 7 8 10 49 |
| # 当行列数分别为10000时,稀疏矩阵的内存大小和生成时间优势均很明显。 |
| n = 10000 |
| m1 = matrix(0, nrow = n, ncol = n) |
| m2 = Matrix(0, nrow = n, ncol = n, sparse = TRUE) |
| object.size(m1); object.size(m2) #求占的内存大小 |
| ## 800000200 bytes |
| ## 41632 bytes |
| system.time(matrix(0, nrow = n, ncol = n)) #统计运行时间 |
| ## user system elapsed |
| ## 0.29 0.14 0.42 |
| system.time(Matrix(0, nrow = n, ncol = n, sparse = TRUE)) |
| ## user system elapsed |
| ## 0 0 0 |
| # 两种矩阵计算区别 |
| n = 1000 |
| dat = sample(c(0, 1), n^2, replace = TRUE, prob = c(0.9, 0.1)) |
| m1 = matrix(dat, nrow = n, ncol = n); m1[1:6, 1:6] |
| ## [,1] [,2] [,3] [,4] [,5] [,6] |
| ## [1,] 0 0 0 0 0 0 |
| ## [2,] 0 0 0 0 0 0 |
| ## [3,] 0 0 0 0 0 1 |
| ## [4,] 0 0 0 0 1 0 |
| ## [5,] 0 1 1 1 0 0 |
| ## [6,] 0 0 0 0 0 1 |
| m2 = Matrix(dat, nrow = n, ncol = n, sparse = TRUE); m2[1:6, 1:6] |
| ## 6 x 6 sparse Matrix of class "dgCMatrix" |
| ## |
| ## [1,] . . . . . . |
| ## [2,] . . . . . . |
| ## [3,] . . . . . 1 |
| ## [4,] . . . . 1 . |
| ## [5,] . 1 1 1 . . |
| ## [6,] . . . . . 1 |
| # 求乘积运算时间对比 |
| system.time(m1 %*% t(m1)) |
| ## user system elapsed |
| ## 1.04 0.00 1.08 |
| system.time(m2 %*% t(m1)) |
| ## user system elapsed |
| ## 0.14 0.00 0.16 |
| ######################################### |
| #总结# |
| matrix(vector,nrow=number_of_rows,ncol=number_of_columns,byrow=T/F) #生成一个矩阵 |
| diag() #生成一个对角矩阵 |
| rep(x,n) #将vector x的值循环n遍 |
| dim(M)# 查看矩阵的维度/行列数 |
| nrow(M) # 提取矩阵的行数 |
| ncol(M) # 提取矩阵的列数 |
| M[1, 2] # 引用元素 |
| M[1:2, 2:3] # 引用元素 |
| colnames(M) = paste0("x_", 1:4) # 给列命名 |
| rownames(M) = (letters[1:3]) # 给行命名 |
| colnames(M) = 1:4 # 给列命名 |
| rownames(M) = c("一","二","三") # 给行命名 |
| colnames(M) # 同样的命令可调用行名 |
| rownames(M) # 同样的命令可调用列名 |
| cbind() #按列合并 |
| rbind() #按行合并 |
| #矩阵的数学操作函数 |
| A+B;A-B;A*B #对矩阵的各个元素完成加减乘运算 |
| A%*%B #矩阵乘法 |
| crossprod(A,B) #矩阵A的转置与矩阵B的乘法 |
| tcrossprod(A,B) #矩阵A与矩阵B的转置的乘法 |
| t(A) #求矩阵A的转置 |
| solve(A) #求矩阵A的逆 |
| eigen(A) #对矩阵进行特征值分解,结果输出特征值及特征向量 |
| svd(A) #对矩阵进行svd奇异值分解,结果可输出矩阵A的奇异值及两个正交阵U,V |
| #rARPACK包 |
| library(rARPACK) #rARPACK包主要针对大规模矩阵运算 |
| eigs() #进行特征值分解 |
| svds() #进行SVD分解 |
| system.time() #统计一个程序运行时间的函数 |
| library(Matrix) #Matrix包提供了很多独特的存储、处理稀疏矩阵的方法(做大规模矩阵运算使用的包) |
| Matrix(vector,nrow=number_of_row,ncol=number_of_column,sparse = TRUE/FALSE)#Sparse=T,则会生成dgCMatrix稀疏矩阵类型 |
| spMatrix(nrow,ncol,i=integer(),j=integer(),x=numeric())#dgTMatrix稀疏矩阵类型 |
| summary() #统一看到spMatrix()填补元素的情况 |
| ######################################### |
最后
以上就是重要朋友最近收集整理的关于R语言-矩阵的全部内容,更多相关R语言-矩阵内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复