Suppose there are two matrices A
and B
:
(A <- mdat <- matrix(c(1,2,3,4,5,6,7,8,9,10,11,12), nrow = 4, ncol = 3))
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
(B <- mdat <- matrix(rev(c(1,2,3,4,5,6,7,8,9,10,11,12)), nrow = 4, ncol = 3))
[,1] [,2] [,3]
[1,] 12 8 4
[2,] 11 7 3
[3,] 10 6 2
[4,] 9 5 1
I want to create array C
defined as below:
C <- array(0, dim=c(4,3,3))
for(i in 1:ncol(A))
for(j in 1:ncol(B))
C[, i, j] = A[,i] + B[,j]
How can this be done nicely without looping?
Repeat each matrix's columns, then add and reset the dimensions:
out <- A[,rep(1:ncol(A),3)] + B[,rep(1:ncol(B),each=3)]
dim(out) <- c(4,3,3)
identical(out,C)
#[1] TRUE
You can construct array with the desired dimension attribute with apply
method (from your comment but switch the positions of A and B):
array(apply(B, 2, "+", A), c(4,3,3))
, , 1
[,1] [,2] [,3]
[1,] 13 17 21
[2,] 13 17 21
[3,] 13 17 21
[4,] 13 17 21
, , 2
[,1] [,2] [,3]
[1,] 9 13 17
[2,] 9 13 17
[3,] 9 13 17
[4,] 9 13 17
, , 3
[,1] [,2] [,3]
[1,] 5 9 13
[2,] 5 9 13
[3,] 5 9 13
[4,] 5 9 13
Would that work ?
i_vec <- rep(1:ncol(A),each = ncol(B))
j_vec <- rep(1:ncol(B),ncol(A))
C <- array(0, dim=c(4,3,3))
Map(function(i,j){C[,i,j] <<- A[,i] + B[,j]},i_vec,j_vec)
# > C
# , , 1
#
# [,1] [,2] [,3]
# [1,] 13 17 21
# [2,] 13 17 21
# [3,] 13 17 21
# [4,] 13 17 21
#
# , , 2
#
# [,1] [,2] [,3]
# [1,] 9 13 17
# [2,] 9 13 17
# [3,] 9 13 17
# [4,] 9 13 17
#
# , , 3
#
# [,1] [,2] [,3]
# [1,] 5 9 13
# [2,] 5 9 13
# [3,] 5 9 13
# [4,] 5 9 13
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.