如何无循环实现以矩阵行列为输入、输出矩阵的函数?
无需循环实现矩阵行×列的逐乘最小值计算
嘿,这个需求完全可以不用写循环就能搞定!在R里,outer()函数就是处理这种“所有行-列组合运算”的利器,刚好能满足你的需求。
核心实现思路
你要的是:对m×k矩阵A的每一行,和k×n矩阵B的每一列,计算它们逐元素相乘后的最小值,最终把这些最小值拼成结果矩阵M。用outer()可以一行代码搞定:
M <- outer(1:nrow(A), 1:ncol(B), function(i, j) min(A[i, ] * B[, j]))
代码拆解
1:nrow(A)和1:ncol(B)分别生成A的行号、B的列号序列outer()会自动遍历这两个序列的所有组合(每一个行号i对应每一个列号j)- 对每一组(i,j),匿名函数会取出A的第i行、B的第j列,逐元素相乘后取最小值,这个值就是M的第i行第j列元素
用你的示例矩阵测试
拿你给出的matrix_A和一个示例matrix_B来验证:
# 你的示例矩阵A(3×5) matrix_A <- matrix(1:15, nrow=3, byrow=TRUE) # 随便定义一个5×2的矩阵B matrix_B <- matrix(c(5,4,3,2,1, 1,2,3,4,5), nrow=5) # 计算结果矩阵M M <- outer(1:nrow(matrix_A), 1:ncol(matrix_B), function(i,j) min(matrix_A[i,] * matrix_B[,j])) # 看看结果 print(M)
运行后会得到:
[,1] [,2] [1,] 5 1 [2,] 6 2 [3,] 7 3
完全符合预期:比如M[1,1]就是min(1×5, 2×4, 3×3, 4×2,5×1)=5,M[3,2]是min(3×1,4×2,5×3,6×4,7×5)=3。
关于“矩阵版sapply”的问题
R里的apply()系列确实可以处理矩阵,但如果是要跨两个矩阵的维度(行×列)做组合运算,outer()是最直接高效的选择。如果你非要用apply()家族的函数,也可以先生成所有行-列索引对,再用apply()处理:
# 生成所有行-列索引组合 idx_pairs <- expand.grid(row = 1:nrow(A), col = 1:ncol(B)) # 计算每个组合的最小值,再转成矩阵 M_matrix <- matrix( apply(idx_pairs, 1, function(x) min(A[x[1], ] * B[, x[2]])), nrow = nrow(A), ncol = ncol(B) )
不过这种写法明显不如outer()简洁,还是推荐优先用outer()。
内容的提问来源于stack exchange,提问作者Glen Ng
相关产品推荐
相关产品推荐

