Search code examples
rmatrixbinaryintegerconcatenation

How to concat/combine two matrices of the same length to "fill in the blanks" of one of the matrices? R Question


I'm working on a binary integer programming assignment and I was hoping there would be a short cut to typing in all the ones and zeros for the constraints. I created two matrices. The first contains all zeros and the second contains all ones.

I have 34 variables and created two matrices like this (though I may not have needed to created these):

zero_constraints = matrix(data = 0, nrow = 1, ncol = 34)
one_constraints = matrix(data = 1, nrow = 1, ncol = 34)

Here's an example of the constraints:

# He therefore decides to include only one collage.
filter(data_raw, data_raw$Medium.Style == "Collage")$ID

output:

[1]  9 16 29 30

I gave each variable a number so these numbers would mean I needed variables 9, 16, 29, and 30 to be 1 and the rest of my variables to be 0.

This where I get lost:

one_constraints[, c(filter(data_raw, data_raw$Medium.Style == "Collage")$ID)]

I know the line above gets me the "ones" I need from my matrix of 34 ones so then I tried to concatenate my two matrices of ones and zeroes:

cat(
    one_constraints[, c(filter(data_raw, data_raw$Medium.Style == "Collage")$ID)],
    zero_constraints[, -c(filter(data_raw, data_raw$Medium.Style == "Collage")$ID)]
)

output:

1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

but this is not the desired output. The ones should not be in a row at the beginning. It should look something like this:

0    0    0    0    0    0    0    0    1     0     0     0     0     0     0     1     0     0   0     0    0     0     0    0     0     0     0     0     1     1     0     0     0     0

If this is too complicated, I can just go with my initial plan to cbind matrices, which is how I created the above.

If you want that code:

cbind(
  matrix(data = 0, nrow = 1, ncol = 8),     # 1-8
  1,                                        # 9
  matrix(data = 0, nrow = 1, ncol = 6),     # 10-15
  1,                                        # 16
  matrix(data = 0, nrow = 1, ncol = 12),    # 17
  1, 1,                                     # 29, 30
  matrix(data = 0, nrow = 1, ncol = 4)      # 31-34
)

Edit I tried this answer:

inds <- c(9, 16, 29, 30)
mat <- matrix(0, ncol = 34)
mat[, inds] <- 1

by doing this:

twnety_one_con <- filter(data_raw, data_raw$Medium.Style == "Collage")$ID
twnety_one_mat <- matrix(data = 0, nrow = 1, ncol =34)
mat <- (twnety_one_mat[, twnety_one_mat] <- 1)

I may be doing it wrong but it doesn't work. It returns a vector of 1 and when I put it my add.constraint bit of code it confirms that it doesn't match vector length


Solution

  • In the OP's function, the index from filter step returns the 'ID's which represents the column index. We only need to assign (<-) the values to 1

    inds <- c(9, 16, 29, 30)
    mat <- matrix(0, ncol = 34)
    mat[, inds] <- 1
    
    
    mat
    #     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] #[,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
    #[1,]    0    0    0    0    0    0    0    0    1     0     0     0     0     0     0     #1     0     0     0     0     0     0     0     0
    #     [,25] [,26] [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34]
    #[1,]     0     0     0     0     1     1     0     0     0     0