矩阵(Matrix)是向量的二维升级版------它是一个行 × 列的表格结构,所有元素必须是同一类型。数组(Array)则是矩阵的更高维扩展。在数据分析和线性代数中,矩阵操作非常常见。
一、什么是矩阵?
矩阵就是一个二维表格,每个格子里的数据类型必须相同:
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
- 行(Row):横着的一排
- 列(Column):竖着的一排
- 所有元素必须是同一类型(数值 / 字符 / 逻辑)
二、创建矩阵
1. 用 matrix() 创建
r
# 把 1到6 排成 2行3列
m <- matrix(1:6, nrow = 2, ncol = 3)
print(m)
运行结果:
txt
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
默认按列填充(先填满第1列,再填第2列)。
2. 按行填充
r
m <- matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE)
print(m)
运行结果:
txt
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
加上 byrow = TRUE 后按行填充。
3. 用向量拼接(rbind / cbind)
r
# 按行拼接(上下拼)
row1 <- c(1, 2, 3)
row2 <- c(4, 5, 6)
m1 <- rbind(row1, row2)
print(m1)
# 按列拼接(左右拼)
col1 <- c(1, 2, 3)
col2 <- c(4, 5, 6)
m2 <- cbind(col1, col2)
print(m2)
运行结果:
txt
[,1] [,2] [,3]
row1 1 2 3
row2 4 5 6
col1 col2
[1,] 1 4
[2,] 2 5
[3,] 3 6
三、访问矩阵元素
用 [行索引, 列索引] 访问:
r
m <- matrix(1:12, nrow = 3, ncol = 4)
print(m)
运行结果:
txt
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
1. 取单个元素
r
m[2, 3] # 第2行第3列
运行结果:
txt
[1] 8
2. 取整行
r
m[1, ] # 第1行,所有列
运行结果:
txt
[1] 1 4 7 10
3. 取整列
r
m[, 2] # 所有行,第2列
运行结果:
txt
[1] 4 5 6
4. 取子矩阵
r
m[1:2, c(1, 3)] # 第1-2行,第1和第3列
运行结果:
txt
[,1] [,2]
[1,] 1 7
[2,] 2 8
四、修改矩阵元素
r
m <- matrix(1:6, nrow = 2, ncol = 3)
print(m)
# 修改单个元素
m[1, 2] <- 99
print(m)
# 修改整行
m[2, ] <- c(10, 20, 30)
print(m)
运行结果:
txt
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
[,1] [,2] [,3]
[1,] 1 99 5
[2,] 2 4 6
[,1] [,2] [,3]
[1,] 1 99 5
[2,] 10 20 30
五、矩阵运算
1. 基本算术运算
r
m1 <- matrix(1:4, nrow = 2)
m2 <- matrix(5:8, nrow = 2)
print(m1 + m2) # 对应元素相加
print(m1 * m2) # 对应元素相乘(不是矩阵乘法!)
print(m1 * 10) # 每个元素乘10
运行结果:
txt
[,1] [,2]
[1,] 6 10
[2,] 8 12
[,1] [,2]
[1,] 5 21
[2,] 12 32
[,1] [,2]
[1,] 10 30
[2,] 20 40
2. 矩阵乘法
r
m1 <- matrix(1:4, nrow = 2)
m2 <- matrix(5:8, nrow = 2)
print(m1 %*% m2) # 真正的矩阵乘法
运行结果:
txt
[,1] [,2]
[1,] 23 31
[2,] 34 46
注意 :
*是逐元素相乘,%*%才是线性代数中的矩阵乘法。
3. 转置
r
m <- matrix(1:6, nrow = 2, ncol = 3)
print(m)
print(t(m)) # 行变列,列变行
运行结果:
txt
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
六、矩阵常用函数
r
m <- matrix(c(85, 92, 78, 90, 67, 88), nrow = 2, ncol = 3, byrow = TRUE)
print(m)
nrow(m) # 行数 → 2
ncol(m) # 列数 → 3
dim(m) # 维度 → 2 3
colSums(m) # 每列求和
rowSums(m) # 每行求和
colMeans(m) # 每列平均
rowMeans(m) # 每行平均
逐个测试:
r
m <- matrix(c(85, 92, 78, 90, 67, 88), nrow = 2, ncol = 3, byrow = TRUE)
print(m)
print("=== 列求和 ===")
print(colSums(m))
print("=== 行求和 ===")
print(rowSums(m))
print("=== 列平均 ===")
print(colMeans(m))
print("=== 行平均 ===")
print(rowMeans(m))
运行结果:
txt
[,1] [,2] [,3]
[1,] 85 92 78
[2,] 90 67 88
[1] "=== 列求和 ==="
[1] 175 159 166
[1] "=== 行求和 ==="
[1] 255 245
[1] "=== 列平均 ==="
[1] 87.5 79.5 83.0
[1] "=== 行平均 ==="
[1] 85.0 81.6666666666667
七、给行列命名
r
scores <- matrix(c(92, 85, 78,
88, 72, 90,
76, 95, 82), nrow = 3, byrow = TRUE)
rownames(scores) <- c("张三", "李四", "王五")
colnames(scores) <- c("数学", "语文", "英语")
print(scores)
运行结果:
txt
数学 语文 英语
张三 92 85 78
李四 88 72 90
王五 76 95 82
命名后可以用名字访问:
r
scores["张三", "数学"] # 张三的数学成绩
scores["李四", ] # 李四所有成绩
scores[, "英语"] # 所有人的英语成绩
运行结果:
txt
[1] 92
数学 语文 英语
88 72 90
张三 李四 王五
78 90 82
八、数组 Array(了解)
数组是矩阵的多维扩展。矩阵是 2 维数组,数组可以有 3 维、4 维......
r
# 创建一个 2×3×2 的三维数组
arr <- array(1:12, dim = c(2, 3, 2))
print(arr)
运行结果:
txt
, , 1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
, , 2
[,1] [,2] [,3]
[1,] 7 9 11
[2,] 8 10 12
访问方式和矩阵类似,多了一个维度:
r
arr[1, 2, 1] # 第1层,第1行第2列 → 3
arr[, , 2] # 第2层的全部
实际工作中,三维及以上数组较少使用,矩阵和向量用得最多。
九、综合实战练习(可直接复制运行)
r
# ==============================
# R 综合练习:矩阵实战
# 场景:班级成绩表分析
# ==============================
# 1. 创建成绩矩阵(5个学生,3门课)
scores <- matrix(
c(92, 85, 78,
88, 72, 90,
76, 95, 82,
65, 58, 70,
95, 88, 92),
nrow = 5, byrow = TRUE
)
rownames(scores) <- c("张三", "李四", "王五", "赵六", "孙七")
colnames(scores) <- c("数学", "语文", "英语")
print("=== 成绩表 ===")
print(scores)
# 2. 每个学生的总分和平均分
print("=== 每人总分 ===")
total <- rowSums(scores)
print(total)
print("=== 每人平均分 ===")
avg <- rowMeans(scores)
print(round(avg, 1))
# 3. 每门课的平均分
print("=== 各科平均分 ===")
print(round(colMeans(scores), 1))
# 4. 找出数学最高分的学生
math_scores <- scores[, "数学"]
best_math <- names(which.max(math_scores))
print(paste("数学最高分:", best_math, max(math_scores), "分"))
# 5. 找出所有不及格的成绩
print("=== 不及格成绩 ===")
for (i in 1:nrow(scores)) {
for (j in 1:ncol(scores)) {
if (scores[i, j] < 60) {
print(paste(rownames(scores)[i], "的",
colnames(scores)[j], ":", scores[i, j], "分(不及格)"))
}
}
}
# 6. 给总分排名
print("=== 总分排名 ===")
ranked <- sort(total, decreasing = TRUE)
for (i in 1:length(ranked)) {
print(paste("第", i, "名:", names(ranked)[i], ",总分", ranked[i]))
}
运行结果:
txt
[1] "=== 成绩表 ==="
数学 语文 英语
张三 92 85 78
李四 88 72 90
王五 76 95 82
赵六 65 58 70
孙七 95 88 92
[1] "=== 每人总分 ==="
张三 李四 王五 赵六 孙七
255 250 253 193 275
[1] "=== 每人平均分 ==="
张三 李四 王五 赵六 孙七
85.0 83.3 84.3 64.3 91.7
[1] "=== 各科平均分 ==="
数学 语文 英语
83.2 79.6 82.4
[1] "数学最高分: 孙七 95 分"
[1] "=== 不及格成绩 ==="
[1] "赵六 的 语文 : 58 分(不及格)"
[1] "=== 总分排名 ==="
[1] "第 1 名: 孙七 ,总分 275"
[1] "第 2 名: 张三 ,总分 255"
[1] "第 3 名: 王五 ,总分 253"
[1] "第 4 名: 李四 ,总分 250"
[1] "第 5 名: 赵六 ,总分 193"