# Getting a 3d array from two 2d arrays

How can I get one 3d array from two 2d arrays?

So, given `A` and `B`:

``````(A <- matrix(1:6, nrow = 3, ncol = 2, dimnames = list(c("A", "B", "C"), c("D", "E"))))
D E
A 1 4
B 2 5
C 3 6
(B <- matrix(1:8, nrow = 4, ncol = 2, dimnames = list(c("F", "G", "H", "I"), c("D", "E"))))
D E
F 1 5
G 2 6
H 3 7
I 4 8
``````

I want to get a new 3d array containing the outer products of the column vectors. Here is a hardcoded example of expected result:

``````(outer(A[,"D"], B[,"D"]))
F G H  I
A 1 2 3  4
B 2 4 6  8
C 3 6 9 12
(outer(A[,"E"], B[,"E"]))
F  G  H  I
A 20 24 28 32
B 25 30 35 40
C 30 36 42 48
``````

I can do a code-it-up, but there must be a functional approach to solve this?

Hi,

I guess this is not really what you want as it is still coded up, but it's the 'cleanest' I can get

``````A <- matrix(1:6, nrow = 3, ncol = 2,
dimnames = list(c("A", "B", "C"), c("D", "E")))
B <- matrix(1:8, nrow = 4, ncol = 2,
dimnames = list(c("F", "G", "H", "I"), c("D", "E")))

C = sapply(1:ncol(A), function(i){
outer(A[,i], B[,i])
}, simplify = F)

array(c(C[], C[]), dim = c(dim(C[]),2),
dimnames = dimnames(C[]))
#> , , 1
#>
#>   F G H  I
#> A 1 2 3  4
#> B 2 4 6  8
#> C 3 6 9 12
#>
#> , , 2
#>
#>    F  G  H  I
#> A 20 24 28 32
#> B 25 30 35 40
#> C 30 36 42 48
``````

Created on 2023-01-13 by the reprex package (v2.0.1)

PJ

1 Like

Thanks for input - I was sort of along the same lines, but was merely wondering if some nice vectorised function, which I was unaware of, would do the trick, alas... So for future reference this is what I converged at:

``````outer_col_prod <- function(X, Y){
outer_prod_list <- lapply(
X = 1:ncol(X),
FUN = function(j){
return( outer(X[,j], Y[,j]) ) })
return(
as.table(
x = array(
data = unlist(outer_prod_list),
dim = c(nrow(X), nrow(Y), ncol(X)),
dimnames = list(
X = rownames(X),
Y = rownames(Y),
Z = colnames(X))))
)
}
``````
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.