今天在工作中遇到一个问题:有一个矩阵,有一个向量,列数是相同的,需要矩阵的每行乘以向量。
例如:
A <- matrix(1:20,nrow=5)
A
## [,1] [,2] [,3] [,4]
## [1,] 1 6 11 16
## [2,] 2 7 12 17
## [3,] 3 8 13 18
## [4,] 4 9 14 19
## [5,] 5 10 15 20
b <- c(3,4,5,6)
b
## [1] 3 4 5 6
我一开始是这么做的:
A*b
## [,1] [,2] [,3] [,4]
## [1,] 3 24 55 96
## [2,] 8 35 72 51
## [3,] 15 48 39 72
## [4,] 24 27 56 95
## [5,] 15 40 75 120
但得到错误结果:1*3, 2*4, 3*5, 4*6, 5*3,是按列广播的,没有一行一行来乘。
网上大概搜了下解决办法:将向量扩展为同等大小的矩阵,再元素对应相乘
B <- matrix(rep(b,nrow(A)),nrow=nrow(A),byrow = T)
B
## [,1] [,2] [,3] [,4]
## [1,] 3 4 5 6
## [2,] 3 4 5 6
## [3,] 3 4 5 6
## [4,] 3 4 5 6
## [5,] 3 4 5 6
A*B
## [,1] [,2] [,3] [,4]
## [1,] 3 24 55 96
## [2,] 6 28 60 102
## [3,] 9 32 65 108
## [4,] 12 36 70 114
## [5,] 15 40 75 120
所以可以定义一个中辍函数%*%,用来实现矩阵按行乘向量。
`%*%` <- function(A,b){
if(ncol(A) != length(b)){
stop("Different length of matrix and vector.")
}
B <- matrix(rep(b,nrow(A)),nrow=nrow(A),byrow = T)
return(A*B)
}
A %*% b
## [,1] [,2] [,3] [,4]
## [1,] 3 24 55 96
## [2,] 6 28 60 102
## [3,] 9 32 65 108
## [4,] 12 36 70 114
## [5,] 15 40 75 120
d <- c(1,2,3,4,5)
try(A %*% d)
总结
这个例子更加反映了R里面矩阵(或数据框)是按列组织的特性,广播时也按列广播,不够则自动循环补齐。
矩阵乘向量,先把向量变成同维度矩阵。