lord.garbage
lord.garbage

Reputation: 5960

Stepwise creation of one big matrix from smaller matrices in R for-loops

I have the following code:

beta <- c(1, 2, 3)
X1 <- matrix(c(1, 1, 1, 1,
               0, 1, 0, 1,
               0, 0, 1, 1),
             nrow = 4,
             ncol = 3)

Z1 <- matrix(c(1, 1, 1, 1,
               0, 1, 0, 1),
             nrow = 4,
             ncol = 2)

Z2 <- matrix(c(1, 1, 1, 1,
               0, 1, 0, 1),
             nrow = 4,
             ncol = 2)

library(MASS)
    S1 <- mvrnorm(70, mu = c(0,0), Sigma = matrix(c(10, 3, 3, 2), ncol = 2))
    S2 <- mvrnorm(40, mu = c(0,0), Sigma = matrix(c(10, 4, 4, 2), ncol = 2))

z <- list()
y <- list()

for(j in 1:dim(S1)[1]){
    for(i in 1:dim(S2)[1]){
        z[[i]] <- X1 %*% beta+Z1 %*% S1[j,]+Z2 %*% S2[i,]+matrix(rnorm(4, mean = 0 , sd = 0.27), nrow = 4)
        Z <- unname(do.call(rbind, z))
    }
    y[[j]] <- Z
    Y <- unname(do.call(rbind, y))
}

X1 is a 4x3, Z1 and Z2 are 4x2 matrices. So everytime X1 %*% beta+X2 %*% S1[j,]+X2 %*% S2[i,]+matrix(rnorm(4, mean = 0 , sd = sigma), nrow = 4) is called it outputs a 4x1 matrix. So far I store all these values in the inner and outer loop in two lists and then call rbind() to transform them into a matrix. Is there a way to directly store them in matrices?

Upvotes: 1

Views: 246

Answers (1)

AndrewMacDonald
AndrewMacDonald

Reputation: 2950

You can avoid using lists if you rely on the apply functions and on vector recycling. I broke down your equation into its parts. (I hope I interpreted it accurately!)

Mb <- as.vector(X1 %*% beta)

M1 <- apply(S1,1,function(x) Z1 %*% x )

M2 <- apply(S2,1,function(x) Z2 %*% x ) + Mb

Mout <- apply(M1,2,function(x) M2 + as.vector(x))

as.vector(Mout) + rnorm(length(Mout), mean = 0 , sd = 0.27)

because the random numbers are added after the matrix multiplication (ie are not involved in any calculation), you can just put them in on the end.

Also note that you can't add a smaller matrix to a larger one, but if you make it a vector first then R will recycle it as necessary. So when Mb (a vector of length 4) is added to a matrix with 4 rows and n columns, it is recycled n times.

Upvotes: 2

Related Questions