Suppose that we have four vectors and each vector is three-dimensional:
v1 <- c(1, 2, 3)
v2 <- c(4, 5, 6)
v3 <- c(2, 2, 2)
v4 <- c(3, 2, 1)
My goal is to create an array containing the outer product of each vector:
tmp_array <- array(NA, dim = c(3, 3, 4))
tmp_array[, , 1] <- outer(v1, v1)
tmp_array[, , 2] <- outer(v2, v2)
tmp_array[, , 3] <- outer(v3, v3)
tmp_array[, , 4] <- outer(v4, v4)
What we have now is a matrix containing the four vectors:
tmp_matrix <- rbind(v1, v2, v3, v4)
and I want to generate tmp_array
by compactly using tmp_matrix
.
I tried outer(t(tmp_matrix), tmp_matrix)
, outer(tmp_matrix, tmp_matrix)
, and so on, but these are not the solution.
How can I create tmp_array
compactly? (i.e. without using loop)
You can use apply(..., simplify = FALSE)
and simplify2array()
to convert the list of outer product matrices to a 3-dimensional array.
simplify2array(apply(tmp_matrix, 1, \(v) outer(v, v), simplify = FALSE))
, , v1
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 2 4 6
[3,] 3 6 9
, , v2
[,1] [,2] [,3]
[1,] 16 20 24
[2,] 20 25 30
[3,] 24 30 36
, , v3
[,1] [,2] [,3]
[1,] 4 4 4
[2,] 4 4 4
[3,] 4 4 4
, , v4
[,1] [,2] [,3]
[1,] 9 6 3
[2,] 6 4 2
[3,] 3 2 1
Using mapply()
you can simplify2array()
by passing the "array"
argument to the simplify
parameter, you can achieve this like so:
mapply(
function(row){
outer(row, row, FUN = `*`)
},
split(
tmp_matrix,
seq_len(nrow(tmp_matrix))
),
SIMPLIFY = "array"
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With