Skip to content

R - 矩阵

矩阵是 R 的基本对象,用于将元素排列成二维矩形网格。一个关键特征是矩阵中的所有元素必须具有相同的原子类型(例如,全部为数值型、全部为字符型)。虽然您可以创建字符型或逻辑型矩阵,但它们在数据分析中的主要用途是存储数值数据以进行数学计算。

在现代 R 中,特别是在 tidyverse 生态系统内,tibble 或 data.frame 通常更受青睐,用于通用数据存储,因为它允许不同类型的列。矩阵对于线性代数、统计建模和高性能计算任务仍然至关重要。

矩阵是使用 matrix() 函数创建的。

在 R 中创建矩阵的基本语法是:

matrix(data, nrow, ncol, byrow = FALSE, dimnames = NULL)

参数说明:

  • data:用于填充矩阵的输入向量。
  • nrow:行数。
  • ncol:列数。
  • byrow:一个逻辑值。如果为 TRUE,则矩阵按行填充。如果为 FALSE(默认值),则按列填充。
  • dimnames:一个可选的包含两个向量的列表,用于命名行和列。

让我们创建几个矩阵,看看参数是如何工作的。我们将使用现代 R 风格,例如 <- 赋值运算符。

# 默认情况下,R 按列填充矩阵。
# 让我们创建一个 4x3 矩阵。
mat_by_col <- matrix(data = 3:14, nrow = 4)
print(mat_by_col)
# 若要按行填充,请设置 byrow = TRUE。
mat_by_row <- matrix(data = 3:14, nrow = 4, byrow = TRUE)
print(mat_by_row)
# 我们还可以添加名称以提高清晰度。
row_names <- paste0("row_", 1:4)
col_names <- paste0("col_", 1:3)
named_mat <- matrix(
data = 3:14,
nrow = 4,
byrow = TRUE,
dimnames = list(row_names, col_names)
)
print(named_mat)

当我们执行上述代码时,它会产生以下结果:

# mat_by_col 的输出(按列填充)
[,1] [,2] [,3]
[1,] 3 7 11
[2,] 4 8 12
[3,] 5 9 13
[4,] 6 10 14
# mat_by_row 的输出(按行填充)
[,1] [,2] [,3]
[1,] 3 4 5
[2,] 6 7 8
[3,] 9 10 11
[4,] 12 13 14
# named_mat 的输出
col_1 col_2 col_3
row_1 3 4 5
row_2 6 7 8
row_3 9 10 11
row_4 12 13 14

您可以使用方括号表示法 [row, column] 访问元素、行或列。将索引留空会选择该维度中的所有元素。

# 让我们使用上一个示例中的 named_mat
# 访问第 1 行、第 3 列的元素
print(named_mat[1, 3])
# 如果存在名称,您也可以使用名称
print(named_mat["row_1", "col_3"])
# 访问整个第 4 行
print(named_mat[4, ])
# 访问整个第 2 列
print(named_mat[, 2])

执行上述代码会产生:

[1] 5
[1] 5
col_1 col_2 col_3
12 13 14
row_1 row_2 row_3 row_4
4 7 10 13

矩阵上的数学运算是 R 的核心优势。理解逐元素运算和真正的矩阵代数之间的区别至关重要。

标准算术运算符逐元素执行计算。这要求两个矩阵具有完全相同的维度。

# 创建两个 2x3 矩阵
matrix1 <- matrix(c(3, 9, -1, 4, 2, 6), nrow = 2)
matrix2 <- matrix(c(5, 2, 0, 9, 3, 4), nrow = 2)
# 逐元素加法
add_result <- matrix1 + matrix2
cat("加法结果:\n")
print(add_result)
# 逐元素乘法
# 这不是矩阵乘法!
mult_result <- matrix1 * matrix2
cat("\n逐元素乘法结果:\n")
print(mult_result)

输出清晰地显示了每个对应的元素都被进行了运算:

Result of addition:
[,1] [,2] [,3]
[1,] 8 -1 5
[2,] 11 13 10
Result of element-wise multiplication:
[,1] [,2] [,3]
[1,] 15 0 6
[2,] 18 36 24

为了进行符合线性代数规则的真正的矩阵乘法,您必须使用 %*% 运算符。内部维度必须匹配(即,第一个矩阵的列数必须等于第二个矩阵的行数)。

# 创建兼容的矩阵以进行乘法
# matrix_A 是 2x3
matrix_A <- matrix(1:6, nrow = 2, byrow = TRUE)
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# matrix_B 是 3x2
matrix_B <- matrix(7:12, nrow = 3, byrow = TRUE)
# [,1] [,2]
# [1,] 7 8
# [2,] 9 10
# [3,] 11 12
# 结果将是一个 2x2 矩阵
matrix_prod <- matrix_A %*% matrix_B
cat("真正的矩阵乘法结果(2x3 %*% 3x2):\n")
print(matrix_prod)

执行此操作可演示正确的矩阵乘法:

Result of true matrix multiplication (2x3 %*% 3x2):
[,1] [,2]
[1,] 58 64
[2,] 139 154
  • 逐元素与矩阵乘法:请务必记住,线性代数乘法要使用 %*%。使用 * 是一个非常常见的错误,会导致不正确的结果。
  • 维度不匹配:如果尝试对维度不兼容的矩阵执行操作,R 将抛出错误。在操作前务必检查 dim()。
  • 数据同质性:请记住,矩阵只能包含一种数据类型。如果您混合类型(例如,数字和文本),R 会将所有元素强制转换为限制最少的类型(通常是字符型),这可能会阻止数学运算。
  • 何时使用矩阵:将矩阵用于数学任务。对于通用数据存储和操作(例如,包含姓名、年龄和 ID 的客户数据表),请使用 tibble 或 data.frame。