R语言中矩阵的常规操作
1、生成矩阵,使用matrix函数
> set.seed(111) ## 设定随机数种子 > vect <- sample(1:10,16, replace = T) > vect [1] 4 3 9 5 3 8 10 1 10 4 8 10 9 8 1 7 > dat <- matrix(vect, nrow = 4, ncol = 4, byrow = T, ## 生成4行4列矩阵,矩阵行列相同,也叫方阵,并指定行名、列名 + dimnames = list(paste0("r",1:4), paste0("c",1:4))) > dat c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > class(dat) [1] "matrix" "array"
2、提取主对角线元素
> dat c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > class(dat) [1] "matrix" "array" > diag(dat) ## 提取主对角线元素 [1] 4 8 8 7
3、提取副对角线元素
> dat c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > diag(dat[,ncol(dat):1]) ## 先列逆向输出,然后取对角线 [1] 5 10 4 9
4、生成对角线为1的对角矩阵(对角矩阵条件:1、矩阵行、列相等,即方阵 2、除对角线元素外其余元素全部为0)
> test1 <- diag(4) ## 生成对角线元素为1的4行4列对角元素 > test1 [,1] [,2] [,3] [,4] [1,] 1 0 0 0 [2,] 0 1 0 0 [3,] 0 0 1 0 [4,] 0 0 0 1 > class(test1) [1] "matrix" "array" > dim(test1) [1] 4 4
5、提取矩阵的下三角矩阵、上三角矩阵
> dat c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > dat[lower.tri(dat)] ## 提取下三角矩阵 [1] 3 10 9 4 8 1 > dat[upper.tri(dat)] ## 提取上三角矩阵 [1] 3 9 10 5 1 10
6、矩阵转置(即行列互换)
> dat c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > t(dat) ## 矩阵转置 r1 r2 r3 r4 c1 4 3 10 9 c2 3 8 4 8 c3 9 10 8 1 c4 5 1 10 7
7、以矩阵下三角矩阵构建对称矩阵(对称矩阵:指以主对角线为对称轴,各元素对应相等的矩阵。)
> test <- dat > test c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > test[upper.tri(test)] <- t(test)[upper.tri(test)] ## 将test上对角矩阵 赋值为test转置后的上对角矩阵 > test c1 c2 c3 c4 r1 4 3 10 9 r2 3 8 4 8 r3 10 4 8 1 r4 9 8 1 7
8、以矩阵的上对角矩阵构建对称矩阵
> test <- dat > test c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > test[lower.tri(test)] <- t(test)[lower.tri(test)] ## 同上 > test c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 9 10 8 10 r4 5 1 10 7
9、将矩阵转换成行索引、列索引、值的形式
(1)列优先
> test <- dat > test c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > r <- rep(1:nrow(test), times = ncol(test)) ## 生成行的索引,优先按列输出 > r [1] 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 > c <- rep(1:ncol(test), each = nrow(test)) ## 生成列的索引,优先按列输出 > c [1] 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 > values <- test[1:(nrow(test)*ncol(test))] ## 输出矩阵的每一个值,优先按列输出 > values [1] 4 3 10 9 3 8 4 8 9 10 8 1 5 1 10 7 > result <- data.frame(r, c, values) > result ## 结果文件 r c values 1 1 1 4 2 2 1 3 3 3 1 10 4 4 1 9 5 1 2 3 6 2 2 8 7 3 2 4 8 4 2 8 9 1 3 9 10 2 3 10 11 3 3 8 12 4 3 1 13 1 4 5 14 2 4 1 15 3 4 10 16 4 4 7
(2)、行优先
> test <- dat > test c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > r <- rep(1:nrow(test), each = ncol(test)) ## 生成行索引,行优先 > r [1] 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 > c <- rep(1:ncol(test), time = nrow(test)) ## 生成列索引,行优先 > c [1] 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 > values <- vector() > for (i in 1:nrow(test)) { ## 利用双循环按行优先导出矩阵的值 + for (j in 1:ncol(test)) { + values <- c(values, test[i,j]) + } + } > values [1] 4 3 9 5 3 8 10 1 10 4 8 10 9 8 1 7 > result <- data.frame(r, c, values) > result ## 结果文件 r c values 1 1 1 4 2 1 2 3 3 1 3 9 4 1 4 5 5 2 1 3 6 2 2 8 7 2 3 10 8 2 4 1 9 3 1 10 10 3 2 4 11 3 3 8 12 3 4 10 13 4 1 9 14 4 2 8 15 4 3 1 16 4 4 7
10、将三列的矩阵(列优先)形式转换为矩阵形式
> test <- dat > test c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > r <- rep(1:nrow(test), time = ncol(test) ) > r [1] 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 > c <- rep(1:ncol(test), each = nrow(test)) > c [1] 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 > values <- as.numeric(dat) > values [1] 4 3 10 9 3 8 4 8 9 10 8 1 5 1 10 7 > result <- data.frame(r, c, values) > result ## 三列的形式,列优先 r c values 1 1 1 4 2 2 1 3 3 3 1 10 4 4 1 9 5 1 2 3 6 2 2 8 7 3 2 4 8 4 2 8 9 1 3 9 10 2 3 10 11 3 3 8 12 4 3 1 13 1 4 5 14 2 4 1 15 3 4 10 16 4 4 7 > if (all(result[,2] == sort(result[,2]))) { ## 利用第二列判断是否是列优先 + row <- max(result[,1]) + col <- max(result[,1]) + re_matrix <- matrix(result[,3], nrow = row, ncol = col, byrow = F) ## byrow = F,表示按列优先输出 + } > re_matrix [,1] [,2] [,3] [,4] [1,] 4 3 9 5 [2,] 3 8 10 1 [3,] 10 4 8 10 [4,] 9 8 1 7
11、将三列的矩阵(行优先)形式转换为矩阵形式
> test <- dat > test c1 c2 c3 c4 r1 4 3 9 5 r2 3 8 10 1 r3 10 4 8 10 r4 9 8 1 7 > r <- rep(1:nrow(test), each = ncol(test)) > r [1] 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 > c <- rep(1:ncol(test), times = nrow(test)) > c [1] 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 > values <- vector() > for (i in 1:nrow(test)) { + for(j in 1:ncol(test)){ + values <- c(values, test[i,j]) + } + } > values [1] 4 3 9 5 3 8 10 1 10 4 8 10 9 8 1 7 > result <- data.frame(r, c, values) > result ## 行优先的三列矩阵 r c values 1 1 1 4 2 1 2 3 3 1 3 9 4 1 4 5 5 2 1 3 6 2 2 8 7 2 3 10 8 2 4 1 9 3 1 10 10 3 2 4 11 3 3 8 12 3 4 10 13 4 1 9 14 4 2 8 15 4 3 1 16 4 4 7 > if (all(result[,2] != sort(result[,2]))) { ## 如果第二列不是排好序,则说明是行优先 + row <- mas(result[,1]) + col <- max(result[,2]) + re_matrix <- matrix(result[,3], nrow = row, ncol = col, byrow = T) ## byrow = T,表示按行优先输出 + } > re_matrix [,1] [,2] [,3] [,4] [1,] 4 3 9 5 [2,] 3 8 10 1 [3,] 10 4 8 10 [4,] 9 8 1 7
12、矩阵加法、减法运算(矩阵加减法运算前提是两个矩阵维度一致,即同行同列)
> mat1 <- matrix(sample(1:10,9), nrow = 3, ncol = 3, byrow = T) ## 生成3行3列矩阵 > mat1 [,1] [,2] [,3] [1,] 4 9 10 [2,] 2 7 6 [3,] 8 1 3 > mat2 <- matrix(sample(1:10,9), nrow = 3, ncol = 3, byrow = T) ## 生成3行3列矩阵 > mat2 [,1] [,2] [,3] [1,] 7 5 9 [2,] 1 4 2 [3,] 6 8 10 > mat1 + mat2 ## 矩阵加法运算 [,1] [,2] [,3] [1,] 11 14 19 [2,] 3 11 8 [3,] 14 9 13 > mat1 - mat2 ## 矩阵减法运算 [,1] [,2] [,3] [1,] -3 4 1 [2,] 1 3 4 [3,] 2 -7 -7
13、矩阵与数值的乘法运算
> mat1 <- matrix(sample(1:10, 9), ncol = 3, nrow = 3, byrow = T) ## 生成3行3列矩阵 > mat1 [,1] [,2] [,3] [1,] 10 8 6 [2,] 4 2 1 [3,] 5 7 9 > 3 * mat1 ## 矩阵与数值的乘法 [,1] [,2] [,3] [1,] 30 24 18 [2,] 12 6 3 [3,] 15 21 27 > mat1 * 2 [,1] [,2] [,3] [1,] 20 16 12 [2,] 8 4 2 [3,] 10 14 18
14、矩阵与矩阵的乘法(矩阵与矩阵乘法的前提是左侧矩阵的列数等于右侧矩阵的行数, 因为乘积的每一项为左侧矩阵每一列的元素与右侧矩阵每一行元素乘积之和,所以必须一一对应, 矩阵相乘的结果矩阵维度为:等于左侧矩阵的行数, 由于右侧矩阵的列数)
> mat1 <- matrix(sample(1:6,6), nrow = 2, ncol = 3, byrow = T) ## 生成2行3列矩阵 > mat1 [,1] [,2] [,3] [1,] 6 5 4 [2,] 1 3 2 > mat2 <- matrix(sample(1:6,12, replace = T), nrow = 3, ncol = 4, byrow = T) ## 生成3行4列矩阵 > mat2 [,1] [,2] [,3] [,4] [1,] 6 4 4 6 [2,] 3 1 2 4 [3,] 3 2 5 5 > mat1 %*% mat2 ## 左侧矩阵列数3, 右侧矩阵函数3,因此可以相乘; 左侧矩阵2行, 右侧矩阵4列, 因此结果为2行4列; 结果中每一项为左侧矩阵行 和 右侧矩阵列乘积之和 [,1] [,2] [,3] [,4] [1,] 63 37 54 76 [2,] 21 11 20 28
15、t(A) %*% B的方法
> A <- matrix(1:12,3,4) ## A为3行4列矩阵 > A [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12 > B <- matrix(1:15,3,5) ## B为3行5列矩阵 > B [,1] [,2] [,3] [,4] [,5] [1,] 1 4 7 10 13 [2,] 2 5 8 11 14 [3,] 3 6 9 12 15 > t(A) %*% B #A的列数不等于B的行数,无法相乘,A转置,变为4行3列矩阵, 列数等于B的行数, 可以相乘 [,1] [,2] [,3] [,4] [,5] [1,] 14 32 50 68 86 [2,] 32 77 122 167 212 [3,] 50 122 194 266 338 [4,] 68 167 266 365 464
使用crossprod函数计算:
> A <- matrix(1:12,3,4) > A [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12 > B <- matrix(1:15,3,5) > B [,1] [,2] [,3] [,4] [,5] [1,] 1 4 7 10 13 [2,] 2 5 8 11 14 [3,] 3 6 9 12 15 > t(A) %*% B [,1] [,2] [,3] [,4] [,5] [1,] 14 32 50 68 86 [2,] 32 77 122 167 212 [3,] 50 122 194 266 338 [4,] 68 167 266 365 464 > crossprod(A,B) ## 与t(A) %*% B的结果相等,据说速度更快 [,1] [,2] [,3] [,4] [,5] [1,] 14 32 50 68 86 [2,] 32 77 122 167 212 [3,] 50 122 194 266 338 [4,] 68 167 266 365 464
16、矩阵求逆(给定n阶方阵A,若存在n阶方阵B满足AB = BA = I,则称A为可逆矩阵,且称B为A的逆矩阵)。 矩阵A与它的逆矩阵的乘积为单位矩阵,单位矩阵为对角线元素为1,其余元素为0的矩阵。
> mat1 <- matrix(sample(1:10, 16, replace = T), 4, 4, byrow = T) ## 生成4行4列矩阵 > mat1 [,1] [,2] [,3] [,4] [1,] 2 3 9 6 [2,] 8 4 4 10 [3,] 6 2 3 2 [4,] 3 6 5 3 > mat2 <- solve(mat1) ## 使用solve函数生成矩阵mat1的逆矩阵mat2 > mat2 [,1] [,2] [,3] [,4] [1,] -0.04219409 -0.002109705 0.20675105 -0.04641350 [2,] -0.10829817 0.011251758 -0.10267229 0.24753868 [3,] 0.14345992 -0.092827004 0.09704641 -0.04219409 [4,] 0.01969058 0.134317862 -0.16315049 -0.04500703 > mat1 %*% mat2 [,1] [,2] [,3] [,4] [1,] 1.000000e+00 0.000000e+00 1.110223e-16 -5.551115e-17 [2,] 0.000000e+00 1.000000e+00 0.000000e+00 -5.551115e-17 [3,] -4.163336e-17 5.551115e-17 1.000000e+00 -8.326673e-17 [4,] 4.857226e-17 5.551115e-17 5.551115e-17 1.000000e+00 > round(mat1 %*% mat2, 5) ## 测试,矩阵与其逆矩阵的乘积为单位矩阵 [,1] [,2] [,3] [,4] [1,] 1 0 0 0 [2,] 0 1 0 0 [3,] 0 0 1 0 [4,] 0 0 0 1
参考:https://blog.csdn.net/yijiaobani/article/details/78880004
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2021-01-31 One of the configured repositories failed (Unknown), and yum doesn't have enough cached data to continue.
2021-01-31 No package epel-release available.
2021-01-31 linux系统redhat7.9安装R