0
votes

I want to fill a 2x2 matrix for every row (N = 500) of my data.

N = 500   # Number of observations
S = 2     # Number of rows and columns of the data

Let's assume this is my example data. It contains 500 observations of 5 covariates.

X <- data.frame(matrix(rexp(2500, rate=.1), ncol=5))
X

From my model, I retrieved 2 coefficients for each covariate.

beta <- data.frame(matrix(rexp(10, rate=.1), ncol=5))
beta

Because I want to fill a 2x2 matrix for each row of my data, I create an output array of size 22n.

output_array = array(NA, dim = c(S,S,N))

Now I want to fill this array in the following way:

  • If the position in the 2x2 matrix is [1,1] or [2,2], I want it to be 1.
  • If the position in the matrix is [1,2], I want it to be the product of the coefficients in the first row of beta and the first row of X
  • If the position in the matrix is [2,1], I want it to be the product of the coefficients in the second row of beta and the first row of X

I want to follow this procedure for all 500 rows of data (...so it goes through the rows), resulting in 500 2x2 matrices (one for each row of data).

My idea was the following function, but it seems that there is a mismatch in dimensions and I'm doing something wrong.

for(t in 1:N){
  betarow = 1
  for (k in 1:S){
    for (j in 1:S){
      if(k == j){
        output_array[t,k,j] = 1;
      } else {
        output_array = X1[t,]*beta[betarow]
          betarow = betarow + 1;
        }
      }
  }
}
1
But in R the product of a 5-element vector and a 5-element vector is another 5-element vector, with the values multiplied element-wise. Are you looking to multiply all ten numbers together and put that into the non-diagonal cells?Allan Cameron
Thanks, Allan. I did not specify it correctly: What I was looking for is the sum of the product of each value of X in this row with the respective beta value (the beta value at the same column-wise position). It would be great to use the function above to implement this. Looking forward to your answer!Scijens
OK Scijens - I have updated my answer which should now do the trick.Allan Cameron

1 Answers

1
votes

In R the product of a 5-element vector and a 5-element vector is another 5-element vector, with the values multiplied element-wise. You are trying to put five numbers into a single "cell". Presumably you meant to get the sum of X[i,] * beta[1,] as a scalar and put that into each cell.

Also, in the line output_array = X1[t,]*beta[betarow] you are over-writing the whole of output_array rather than just a single element of it.

Remember to take advantage of vectorization in R where possible. We can just create the matrices individually in an lapply, and create our whole array that way:

X    <- data.frame(matrix(rexp(2500, rate=.1), ncol = 5))
beta <- data.frame(matrix(rexp(10, rate=.1), ncol = 5))

output_array <- `dim<-`(unlist(lapply(seq(nrow(X)), function(i) { 
  matrix(c(1, sum(X[i,] * beta[1,]), sum(X[i,] * beta[2,]), 1), nrow = 2)
})), c(2, 2, nrow(X)))

So the first three "slices" of output_array look like this:

output_array[,,1:3]
#> , , 1
#> 
#>          [,1]    [,2]
#> [1,]   1.0000 184.826
#> [2,] 677.8113   1.000
#> 
#> , , 2
#> 
#>          [,1]     [,2]
#> [1,]   1.0000 263.7545
#> [2,] 335.3813   1.0000
#> 
#> , , 3
#> 
#>          [,1]     [,2]
#> [1,]   1.0000 156.0655
#> [2,] 235.1856   1.0000