我想写一个函数,它将矩阵的列和行作为参数,并给出一个矩阵作为输出。
例如,一个函数通过 k 矩阵 和列<获取 m 的行 i 通过 n 矩阵 B 的 k 的em> j ,并返回带有元素的矩阵 M m_i,j 等于min(A[i,] * B[,j])
(逐元素乘法):
有没有简单的方法可以避免使用循环?是否存在sapply
矩阵的等价物?
> matrix_A
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 2 3 4 5 6
[3,] 3 4 5 6 7
[4,] 0 1 2 3 4
[5,] 5 6 7 8 9
> matrix_B
[,1] [,2] [,3] [,4] [,5]
[1,] 7 6 5 4 3
[2,] 6 5 4 3 2
[3,] 1 2 3 4 5
[4,] 8 7 6 5 4
[5,] 9 8 7 6 5
>
> output_matrix <- matrix(, nrow=nrow(matrix_A), ncol=ncol(matrix_B))
> for (row_i in 1:nrow(matrix_A)) {
+ for (col_j in 1:ncol(matrix_B)) {
+ output_matrix[row_i, col_j] <- min(matrix_A[row_i,]*matrix_B[,col_j])
+ }
+ }
> output_matrix
[,1] [,2] [,3] [,4] [,5]
[1,] 3 6 5 4 3
[2,] 4 8 10 8 6
[3,] 5 10 15 12 8
[4,] 0 0 0 0 0
[5,] 7 14 21 18 12
>
答案 0 :(得分:4)
使用基础R中的row no-gutters mt-auto
,
style={{ display: 'flex', flex: 1, flexDirection: 'row' }}
给出,
apply
完全矢量化的解决方案可以是,
apply(m2, 2, function(i) apply(m1, 1, function(j) min(j*i)))
答案 1 :(得分:1)
这里我们使用pmap
迭代A和B的行和列:
library(tidyverse)
pmap_dbl(expand.grid(1:nrow(A), 1:nrow(B)), ~ min(A[..1, ] * B[ , ..2])) %>%
matrix(nrow=5)
[,1] [,2] [,3] [,4] [,5] [1,] 3 6 5 4 3 [2,] 4 8 10 8 6 [3,] 5 10 15 12 8 [4,] 0 0 0 0 0 [5,] 7 14 21 18 12
答案 2 :(得分:1)
我们使用expand.grid
来创建行和列对的所有可能组合。然后,我们使用mapply
将所有行列组合元素相乘,然后从中选择min
。
mat <- expand.grid(1:nrow(A),1:nrow(B))
mapply(function(x, y) min(matrix_A[x,] * matrix_B[, y]) , mat[,1], mat[,2])
#[1] 3 4 5 0 7 6 8 10 0 14 5 10 15 0 21 4 8 12 0 18 3 6 8 0 12
假设matrix_A
,matrix_B
和output_matrix
都具有相同的维度,我们可以relist
mapply
的输出来获取原始尺寸。
output_matrix <- mapply(function(x, y) min(matrix_A[x,] * matrix_B[, y]),
mat[,1], mat[,2])
relist(output_matrix, matrix_A)
# [,1] [,2] [,3] [,4] [,5]
#[1,] 3 6 5 4 3
#[2,] 4 8 10 8 6
#[3,] 5 10 15 12 8
#[4,] 0 0 0 0 0
#[5,] 7 14 21 18 12
答案 3 :(得分:1)
对于此特定示例,您可以避免R循环(* apply函数也是循环)。通常有效的解决方案是可能的,但需要一个特定的算法,如我在此演示。如果您不需要优化速度,请使用循环。您的for
循环提供了最佳的可读性,并且易于理解。
matrix_A <- matrix(c(1,2,3,0,5,
2,3,4,1,6,
3,4,5,2,7,
4,5,6,3,8,
5,6,7,4,9), 5)
matrix_B <- matrix(c(7,6,1,8,9,
6,5,2,7,8,
5,4,3,6,7,
4,3,4,5,6,
3,2,5,4,5), 5)
#all combinations of i and j
inds <- expand.grid(seq_len(nrow(matrix_A)), seq_len(ncol(matrix_B)))
#subset A and transposed B then multiply the resulting matrices
#then calculate rowwise min and turn result into a matrix
library(matrixStats)
matrix(rowMins(matrix_A[inds[[1]],] * t(matrix_B)[inds[[2]],]), nrow(matrix_A))
# [,1] [,2] [,3] [,4] [,5]
#[1,] 3 6 5 4 3
#[2,] 4 8 10 8 6
#[3,] 5 10 15 12 8
#[4,] 0 0 0 0 0
#[5,] 7 14 21 18 12