How to multiply columns of two matrix with all combinations - r

I like to multiply all possible combinations of columns of two matrices that has same rows. Which means two matrices, e.g., a[3x3] and b[3x4] will generate 3x4 matrices with elements a[i,j]*a[k,j]. (i and k represents rows ranging from 1 to 3 and j represent column from 1 to 4)
I have created an example, that can do this job but was looking for elegant solution without for loop.
a <- matrix(1:12,3,4)
b <- matrix(1:9,3,3)
comb<-matrix(NA,3,(ncol(a)*ncol(b)))
for (i in 1:nrow(a)){
comb[i,]<-apply(expand.grid(a[i,],b[i,]),1,prod)
}
comb
Here a is 3x3 matrix, b is 3x4 matrix, and comb gives output of 3x12 matrix by multiplying various columns. I am looking for elegant solution that can be generalized to such multiplication to more than two matrices.

Here are a few one-liners in decreasing order of length:
t(sapply(1:3, function(i) tcrossprod(a[i, ], b[i, ])))
t(mapply(outer, split(a, 1:3), split(b, 1:3)))
matrix(apply(a %o% b, c(2, 4), diag), 3)
(b %x% a)[!!diag(3), ]

Related

Sapply function for element-wise calculation a matrix in R

I have an (5x4) matrix in R, namely data defined as follows:
set.seed(123)
data <- matrix(rnorm(5*4,mean=0,sd=1), 5, 4)
and I want to create 4 different matrices that follows this formula: Assume that data[,1] = [A1,A2,A3,A4,A5]. I want to create the following matrix:
A1-A1 A1-A2 A1-A3 A1-A4 A1-A5
A2-A1 A2-A2 A2-A3 A2-A4 A2-A5
G1 = A3-A1 A3-A2 A3-A3 A3-A4 A3-A5
A4-A1 A4-A2 A4-A3 A4-A4 A4-A5
A5-A1 A5-A2 A5-A3 A5-A4 A5-A5
Similarly for the other columns i want to calculate at once all the G matrices (G1,G2,G3,G4). How can i achieve that with the sapply funciton?
We may use elementwise subtraction of column with outer
outer(data[,1], data[,1], `-`)
If it should be done on each column, loop over the columns (or do asplit with MARGIN = 2 to split by column), loop over the list and apply the outer
lapply(asplit(data, 2), function(x) outer(x, x, `-`))

operating on pairs of columns in R (or numpy)

I have two matrices: A (k rows, m columns), B(k rows, n columns)
I want to operate on all pairs of columns (one from A and one from B), the result should be a matrix C (m rows, n columns) where C[i,j] = f(A[,i],B[,j])
now, if the function f was the sum of the dot product, then the whole thing was just a simple multiplication of matrices (C = t(A) %*% B)
but my f is different (specifically, I count the number equal entries:
f = function(x,y) sum(x==y)
my question if there is a simple (and fast, because my matrices are big) way to compute the result?
preferably in R, but possibly in python (numpy). I thought about using outer(A,B,"==") but this results in a 4 dimensional array which I havent figured out what exactly to do with it.
Any help is appreciated
In R, we can split them into list and apply the function f with a nested lapply/sapply
lapply(asplit(A, 2), function(x) sapply(asplit(B, 2), function(y) f(x, y)))
Or using outer after converting to data.frame because the unit will be column, while for matrix, it is a single element (as matrix is a vector with dim attributes)
outer(as.data.frame(A), as.data.frame(B), FUN = Vectorize(f))
data
A <- cbind(1:5, 6:10)
B <- cbind(c(1:3, 1:2), c(5:7, 6:7))

Creating multiple matrices with a for loop

I would like to create ncol(y) number of matrices taking each column from y matrix and replicating it rep number of times. I am not doing the for loop right though. To reiterate, below I would like to get three separate matrices, the first one would have values of 1 to 100 repeated 200 times (they come from the first columns of y), second would have vector 101-200 repeated 200 times (2nd column of y) as well and the third one would have values 201-300 repeated 200 times (3rd column of y). Preferably the output name would be matrix1, matrix2 or a list.
y <- matrix(1:300,100,3)
rep = 200
for (i in 1:ncol(y)) {
newmatrix <- replicate(rep,y[,i])
valuematrix[[i]] <- newmatrix
}
You're missing the initialization of valuematrix. You can do this through
valuematrix <- list()
just before the for loop.
You might also consider using lapply to solve this problem. It automatically stores the matrices in a list.
y <- matrix(1:300, 100, 3)
rep = 200
matList <- lapply(1:ncol(y), function(i) replicate(rep, y[,i]))

Creating a matrix from operations done on another dataset

I have a large dataset, X with 58140 columns, filled with either 1 or 0
I would like to create a 58139 x 58139 matrix from the information of the 58139 columns in the dataset.
For each Aij in the matrix I would like to find the number of common rows which contain the value 1 for Column i+1 and Column J+1 from X.
I figured I can do this through sum(X[[2]]+X[[3]] == 2) for the A12 element of the matrix.
The only problem left is a way to code the matrix in.
You can use mapply. That returns a numeric vector. Then you can just wrap it in a call to matrix and ignore the first row and column.
# sample data
set.seed(123)
X <- data.frame(matrix(rbinom(200, 1, .5), nrow=10))
#
A <- matrix(mapply(function(i, j) sum(rowSums(X[, c(i,j)])==2),
i=rep(1:ncol(X), ncol(X)),
j=rep(1:ncol(X), each=ncol(X))),
ncol=ncol(X))[-1, -1]
A

R: extract parts of matrices in loops - loop only run once

I am not an advanced user, but I have been trying to solve this problem for many hours now and I do not know how else to proceed.
SETTING: I have a 2X10000 matrix, which is constituted of 10000 repetitions of 2 variables, call them a and b,in row 1 and 2 respectively.
I need an operation repeated for every column (i.e. 10000 times), hence the loop.
The operation is the following:
for every column [a b]', create a 2x2 matrix looking like this:
[a b]
[b a]
then transpose this matrix and multiply it by the original column column. At the end I should obtain, for each original column [a b]', another column but with two different values.
I build the 2x10000 matrix to contain the result:
R <- 10000
a <- matrix(rep(1, 200), nrow=2, ncol=R)
Gamma is the 2x10000 matrix whose columns I am using. Then I apply the following loop:
for (j in 1:R) {
Big_Gamma = matrix(c(Gamma[1, j], Gamma[2, j], Gamma[2, j], Gamma[1, j]), nrow=2, ncol=2);
a <- solve(Big_Gamma)%*%Gamma[, j];
}
Big_Gamma is the 2x2 matrix I need to invert and multiply by the original vector.
Again, I need this done for each of the 10000 vectors and I need another vector (of equal dimension as the original one) as output (if possible).
I tried different specifications, also in the way I extract the columns, but it always only runs once (i.e. the matrix a changes and becomes a 2x1 one)
I have looked for hours on various sites and could not find an answer. I hope the question is not too stupid.
Thank you in advance, soo much!
You are overwriting a on each iteration. Try:
R <- 10000
a <- matrix(rep(1, 200), nrow=2, ncol=R)
for (j in 1:R) {
Big_Gamma = matrix(c(Gamma[1, j], Gamma[2, j], Gamma[2, j], Gamma[1, j]), nrow=2, ncol=2);
a[, j] <- solve(Big_Gamma)%*%Gamma[, j];
}

Resources