Search code examples
rvectorrep

Create a complicated matrix from vector in r


I have a vector of sample sizes for 4 populations: 3 2 1 4 which sums to 10 individuals. I need code that can dynamically (so can be used in different situations) make a matrix of 1's and 0's with 10 rows and 4 columns that has 3 1's then the rest of that column 0's then the next column has 3 0's then 2 1's then the rest 0's and so on as shown below:

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

Input:

nSamples <- c(3,2,1,4)

Solution

  • Here's a possible two-step approach.

    # create a matrix of zeros first
    m <- matrix(0L, ncol = length(nSamples), nrow = sum(nSamples))
    # then replace relevant 0s with 1s:
    m[cbind(1:nrow(m), rep(seq_along(nSamples), nSamples))] <- 1L
    m
    #      [,1] [,2] [,3] [,4]
    # [1,]    1    0    0    0
    # [2,]    1    0    0    0
    # [3,]    1    0    0    0
    # [4,]    0    1    0    0
    # [5,]    0    1    0    0
    # [6,]    0    0    1    0
    # [7,]    0    0    0    1
    # [8,]    0    0    0    1
    # [9,]    0    0    0    1
    # [10,]   0    0    0    1
    

    The "trick", if you will, is

    rep(seq_along(nSamples), nSamples)
    #[1] 1 1 1 2 2 3 4 4 4 4