Use 'sample' with my 3 matrices to produce new matrices?

I have 3 simple matrices. I want to use sample with replace (aka bootstrap) to create 5 new matrices.

Minimal reprex:

my_mat1 <- matrix(c(10,20,50,11,21,51,12,22,52), nrow=3, ncol=3)
my_mat2 <- my_mat1 + 1
my_mat3 <- my_mat2 + 1.5

#Here's what my_mat1 looks like:
my_mat1
     [,1] [,2] [,3]
[1,]   10   11   12
[2,]   20   21   22
[3,]   50   51   52

I want to use these 3 simple matrices, to make 5 new ones. Using built-in sample functionthis is super easy for one square the matrix. For example, the top left square of all 3 matrices is 10, 11, & 12.5

If I want to create 5 bootstrapped values from these 3 numbers, it's easy! I just do

lapply(1:5, function(i) sample(c(10,11,12.5), replace=TRUE))
[[1]]
[1] 10.0 12.5 10.0

[[2]]
[1] 11.0 12.5 12.5

[[3]]
[1] 10 10 11

[[4]]
[1] 12.5 11.0 10.0

[[5]]
[1] 10 11 10

But how can I apply this to all squares of my 3 matrices to make the 5 new matrices?

my_mat1 <- matrix(c(10,20,50,11,21,51,12,22,52), nrow=3, ncol=3)
my_mat2 <- my_mat1 + 1
my_mat3 <- my_mat2 + 1.5

five_bs <- function(m) {
    # return five bootstrapped samples of the matrix m
    return(lapply(1:5, function(x) m[sample.int(nrow(m)), ]))
}

# nedted list
lapply(list(my_mat1, my_mat2, my_mat3), five_bs)
#> [[1]]
#> [[1]][[1]]
#>      [,1] [,2] [,3]
#> [1,]   20   21   22
#> [2,]   10   11   12
#> [3,]   50   51   52
#> 
#> [[1]][[2]]
#>      [,1] [,2] [,3]
#> [1,]   50   51   52
#> [2,]   10   11   12
#> [3,]   20   21   22
#> 
#> [[1]][[3]]
#>      [,1] [,2] [,3]
#> [1,]   20   21   22
#> [2,]   50   51   52
#> [3,]   10   11   12
#> 
#> [[1]][[4]]
#>      [,1] [,2] [,3]
#> [1,]   10   11   12
#> [2,]   20   21   22
#> [3,]   50   51   52
#> 
#> [[1]][[5]]
#>      [,1] [,2] [,3]
#> [1,]   50   51   52
#> [2,]   20   21   22
#> [3,]   10   11   12
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#>      [,1] [,2] [,3]
#> [1,]   21   22   23
#> [2,]   11   12   13
#> [3,]   51   52   53
#> 
#> [[2]][[2]]
#>      [,1] [,2] [,3]
#> [1,]   21   22   23
#> [2,]   51   52   53
#> [3,]   11   12   13
#> 
#> [[2]][[3]]
#>      [,1] [,2] [,3]
#> [1,]   21   22   23
#> [2,]   51   52   53
#> [3,]   11   12   13
#> 
#> [[2]][[4]]
#>      [,1] [,2] [,3]
#> [1,]   51   52   53
#> [2,]   21   22   23
#> [3,]   11   12   13
#> 
#> [[2]][[5]]
#>      [,1] [,2] [,3]
#> [1,]   11   12   13
#> [2,]   21   22   23
#> [3,]   51   52   53
#> 
#> 
#> [[3]]
#> [[3]][[1]]
#>      [,1] [,2] [,3]
#> [1,] 12.5 13.5 14.5
#> [2,] 52.5 53.5 54.5
#> [3,] 22.5 23.5 24.5
#> 
#> [[3]][[2]]
#>      [,1] [,2] [,3]
#> [1,] 12.5 13.5 14.5
#> [2,] 22.5 23.5 24.5
#> [3,] 52.5 53.5 54.5
#> 
#> [[3]][[3]]
#>      [,1] [,2] [,3]
#> [1,] 22.5 23.5 24.5
#> [2,] 52.5 53.5 54.5
#> [3,] 12.5 13.5 14.5
#> 
#> [[3]][[4]]
#>      [,1] [,2] [,3]
#> [1,] 52.5 53.5 54.5
#> [2,] 22.5 23.5 24.5
#> [3,] 12.5 13.5 14.5
#> 
#> [[3]][[5]]
#>      [,1] [,2] [,3]
#> [1,] 52.5 53.5 54.5
#> [2,] 22.5 23.5 24.5
#> [3,] 12.5 13.5 14.5

# unnested
do.call(c, lapply(list(my_mat1, my_mat2, my_mat3), five_bs))
#> [[1]]
#>      [,1] [,2] [,3]
#> [1,]   50   51   52
#> [2,]   20   21   22
#> [3,]   10   11   12
#> 
#> [[2]]
#>      [,1] [,2] [,3]
#> [1,]   10   11   12
#> [2,]   50   51   52
#> [3,]   20   21   22
#> 
#> [[3]]
#>      [,1] [,2] [,3]
#> [1,]   10   11   12
#> [2,]   50   51   52
#> [3,]   20   21   22
#> 
#> [[4]]
#>      [,1] [,2] [,3]
#> [1,]   20   21   22
#> [2,]   50   51   52
#> [3,]   10   11   12
#> 
#> [[5]]
#>      [,1] [,2] [,3]
#> [1,]   10   11   12
#> [2,]   20   21   22
#> [3,]   50   51   52
#> 
#> [[6]]
#>      [,1] [,2] [,3]
#> [1,]   51   52   53
#> [2,]   11   12   13
#> [3,]   21   22   23
#> 
#> [[7]]
#>      [,1] [,2] [,3]
#> [1,]   11   12   13
#> [2,]   51   52   53
#> [3,]   21   22   23
#> 
#> [[8]]
#>      [,1] [,2] [,3]
#> [1,]   11   12   13
#> [2,]   51   52   53
#> [3,]   21   22   23
#> 
#> [[9]]
#>      [,1] [,2] [,3]
#> [1,]   11   12   13
#> [2,]   21   22   23
#> [3,]   51   52   53
#> 
#> [[10]]
#>      [,1] [,2] [,3]
#> [1,]   11   12   13
#> [2,]   21   22   23
#> [3,]   51   52   53
#> 
#> [[11]]
#>      [,1] [,2] [,3]
#> [1,] 12.5 13.5 14.5
#> [2,] 22.5 23.5 24.5
#> [3,] 52.5 53.5 54.5
#> 
#> [[12]]
#>      [,1] [,2] [,3]
#> [1,] 22.5 23.5 24.5
#> [2,] 52.5 53.5 54.5
#> [3,] 12.5 13.5 14.5
#> 
#> [[13]]
#>      [,1] [,2] [,3]
#> [1,] 22.5 23.5 24.5
#> [2,] 12.5 13.5 14.5
#> [3,] 52.5 53.5 54.5
#> 
#> [[14]]
#>      [,1] [,2] [,3]
#> [1,] 52.5 53.5 54.5
#> [2,] 12.5 13.5 14.5
#> [3,] 22.5 23.5 24.5
#> 
#> [[15]]
#>      [,1] [,2] [,3]
#> [1,] 22.5 23.5 24.5
#> [2,] 12.5 13.5 14.5
#> [3,] 52.5 53.5 54.5

Created on 2021-06-08 by the reprex package (v1.0.0)

1 Like

Depending on the type of sampling you want, you might use replace = TRUE as second argument to sample.int.

1 Like

This is really close to what I am trying to get, and certainly more elaborate that what I was attempting, thanks for that!

So I think your way produces 15 total matrices, because the five_bs function makes 5 bootstrapped matrices for each input matrix - am I getting that right? I want to have a total of 5 matrices, however. The important thing I definitely can't seem to get the hang of is keep the indices correct...

for example, if the upper left square of the input matrix1/2/3 is 10/11/12 (respectively), maybe the 5 bootstrapped samples would be "10, 12, 12, 12, 11".

So I want the upper left squares to be:
bs_matrix1 = 10
bs_matrix2 = 12
bs_matrix3 = 12
bs_matrix 4= 12
bs_matrix5 = 11

And continue so that the indicies of square 2 are preserved, square 3, etc etc.

I feel your method is great! Can it be modified to produce this?

Thanks a lot for this!

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.