我目前正在学习 R 中的矩阵运算,在将向量与矩阵相乘时遇到了我没有预料到的输出。我的理解是乘法将按元素进行,但输出表明并非如此。我运行的代码如下:
num_matrix <- matrix(1:9, byrow = TRUE, nrow = 3)
new_matrix <- c(1,2,3) * num_matrix
print(new_matrix)
The output I got is:
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 8 10 12
[3,] 21 24 27
这看起来像是向量 c(1,2,3) 已与 num_matrix 的每一列相乘,这与我最初对按行操作的预期相矛盾。有人可以解释为什么乘法的行为是这样的,而不是像我预期的那样按行进行吗?
此外,如果我想将向量与矩阵的每一行相乘,而不是与每一列相乘,如何在 R 中实现这一点?
感谢您的帮助!
R 中的矩阵是按列优先顺序排列的向量。您可以转置矩阵,使元素沿着以前的行的列回收,然后转回:
(want_matrix <- t(t(num_matrix) * 1:3))
#> [,1] [,2] [,3]
#> [1,] 1 4 9
#> [2,] 4 10 18
#> [3,] 7 16 27
为了好玩,这里有一些其他方法及其基准。请注意,当输入较小时,将其视为 matrix 乘法将是最快的,但不能很好地扩展 - 转置更加一致。
f1 <- \(m, v) t(t(m) * v)
f2 <- \(m, v) apply(m, 1, \(r) r*v)
f3 <- \(m, v) sweep(m, 1, v, `*`)
f4 <- \(m, v) m %*% diag(v)
bench <- function(n) {
m <- matrix(rnorm(n*n), ncol=n)
v <- runif(n)
microbenchmark::microbenchmark(
transpose=f1(m,v),
apply=f2(m,v),
sweep=f3(m,v),
`%*%`=f4(m,v)
)
}
bench(10)
#> Unit: microseconds
#> expr min lq mean median uq max
#> transpose 5.8 6.1 6.718 6.20 6.5 20.5
#> apply 26.0 27.4 29.764 28.10 29.8 58.3
#> sweep 20.7 21.7 24.351 22.85 23.6 99.8
#> %*% 2.2 2.4 3.176 2.60 2.8 26.2
bench(100)
#> Unit: microseconds
#> expr min lq mean median uq max
#> transpose 36.0 61.45 165.074 63.35 67.70 10192.8
#> apply 197.7 241.55 285.582 268.25 309.70 641.0
#> sweep 57.7 83.65 91.682 88.60 94.25 224.9
#> %*% 460.5 493.85 504.451 496.95 503.65 829.9