Let's say I have a numerical matrix
:
set.seed(1)
mat <- matrix(rnorm(1000), ncol = 100)
I want to generate all vectors that are the result of the element-wise product of all unique pairs of vectors in mat
.
How can we improve below code:
all.pairs <- t(combn(1:ncol(mat), 2))
res <-
do.call(cbind,
lapply(1:nrow(all.pairs),
function(p) mat[, all.pairs[p, 1]] * mat[, all.pairs[p, 2]]))
To pick out single or multiple columns use the select() function. The select() function expects a dataframe as it's first input ('argument', in R language), followed by the names of the columns you want to extract with a comma between each name.
Similar to vectors, square brackets [] can be used to select one or multiple elements from a matrix. Since matrices are two dimensional, a comma is needed to separate the rows and columns. For example: my_matrix[1,2] selects the element at the first row and second column (row 1, column 2)
Similar to vectors, you can use the square brackets [ ] to select one or multiple elements from a matrix. Whereas vectors have one dimension, matrices have two dimensions. You should therefore use a comma to separate the rows you want to select from the columns.
We could do:
n <- ncol(mat)
lst <- lapply(1:n, function (i) mat[,i] * mat[,i:n])
do.call(cbind, lst)
Or, here is an even faster way:
n <- ncol(mat)
j1 <- rep.int(1:n, n:1)
j2 <- sequence(n:1) - 1L + j1
mat[, j1] * mat[, j2]
Note, the above will include the multiplication of a column to itself. If you want to forbid that, use
n <- ncol(mat)
lst <- lapply(1:(n-1), function (i) mat[,i] * mat[,(i+1):n])
do.call(cbind, lst)
and
n <- ncol(mat)
j1 <- rep.int(1:(n-1), (n-1):1)
j2 <- sequence((n-1):1) + j1
mat[, j1] * mat[, j2]
Actually, j1
and j2
created above are just the 1st and 2nd row of combn(1:ncol(mat),2)
. So, if you still want to stay with combn
, use
all.pairs <- combn(1:ncol(mat),2)
mat[, all.pairs[1,]] * mat[, all.pairs[2,]]
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