First, a terminology aspect: when you write "sample", I expect a random sampling (which is the case for bootstrap), but in your example you seem to want all combinations (e.g. for a permutation test).
Assuming the latter, I don't think you actually need to compute the matrices "red", "green" and "blue", you only need their rownames and colnames (which you can store as vectors). Then you can get all permutations using expand.grid()
, and finally for each combination you can get the corresponding permuted matrix. So this code should do what you want:
colors <- c("red", "green", "blue")
rows <- lapply(1:3,
\(i) c(9,4,0) + i) |>
setNames(colors)
cols <- lapply(1:3,
\(i) c(1,3,7) + i) |>
setNames(colors)
rows
#> $red
#> [1] 10 5 1
#>
#> $green
#> [1] 11 6 2
#>
#> $blue
#> [1] 12 7 3
cols
#> $red
#> [1] 2 4 8
#>
#> $green
#> [1] 3 5 9
#>
#> $blue
#> [1] 4 6 10
all_combinations <- expand.grid(rows = rows, cols = cols)
all_combinations
#> rows cols
#> 1 10, 5, 1 2, 4, 8
#> 2 11, 6, 2 2, 4, 8
#> 3 12, 7, 3 2, 4, 8
#> 4 10, 5, 1 3, 5, 9
#> 5 11, 6, 2 3, 5, 9
#> 6 12, 7, 3 3, 5, 9
#> 7 10, 5, 1 4, 6, 10
#> 8 11, 6, 2 4, 6, 10
#> 9 12, 7, 3 4, 6, 10
mats <- list()
for(i in seq_len(nrow(all_combinations))){
mats[[i]] <- all_combinations$rows[[i]] %*% t(all_combinations$cols[[i]])
}
mats
#> [[1]]
#> [,1] [,2] [,3]
#> [1,] 20 40 80
#> [2,] 10 20 40
#> [3,] 2 4 8
#>
#> [[2]]
#> [,1] [,2] [,3]
#> [1,] 22 44 88
#> [2,] 12 24 48
#> [3,] 4 8 16
#>
#> [[3]]
#> [,1] [,2] [,3]
#> [1,] 24 48 96
#> [2,] 14 28 56
#> [3,] 6 12 24
#>
#> [[4]]
#> [,1] [,2] [,3]
#> [1,] 30 50 90
#> [2,] 15 25 45
#> [3,] 3 5 9
#>
#> [[5]]
#> [,1] [,2] [,3]
#> [1,] 33 55 99
#> [2,] 18 30 54
#> [3,] 6 10 18
#>
#> [[6]]
#> [,1] [,2] [,3]
#> [1,] 36 60 108
#> [2,] 21 35 63
#> [3,] 9 15 27
#>
#> [[7]]
#> [,1] [,2] [,3]
#> [1,] 40 60 100
#> [2,] 20 30 50
#> [3,] 4 6 10
#>
#> [[8]]
#> [,1] [,2] [,3]
#> [1,] 44 66 110
#> [2,] 24 36 60
#> [3,] 8 12 20
#>
#> [[9]]
#> [,1] [,2] [,3]
#> [1,] 48 72 120
#> [2,] 28 42 70
#> [3,] 12 18 30
Created on 2022-12-04 by the reprex package (v2.0.1)
If what you want is indeed a (random) sampling with replacement, i.e. the same values can appear an arbitrary number of times, I still see two possibilities. If you sample a colname or rowname all at once, this is obtained simply by replacing the call to expand.grid()
with calls to sample()
with replace = TRUE
.
Note that here the number of samples is a parameter you decide about, it's not determined by the size of your matrices. For bootstrap, it's common to have big numbers (e.g. 1000).
set.seed(123)
colors <- c("red", "green", "blue")
rows <- lapply(1:3,
\(i) c(9,4,0) + i) |>
setNames(colors)
cols <- lapply(1:3,
\(i) c(1,3,7) + i) |>
setNames(colors)
rows
#> $red
#> [1] 10 5 1
#>
#> $green
#> [1] 11 6 2
#>
#> $blue
#> [1] 12 7 3
cols
#> $red
#> [1] 2 4 8
#>
#> $green
#> [1] 3 5 9
#>
#> $blue
#> [1] 4 6 10
nb_sampled <- 5
sampled_rows <- sample(rows, size = nb_sampled, replace = TRUE)
sampled_cols <- sample(cols, size = nb_sampled, replace = TRUE)
sampled_rows
#> $blue
#> [1] 12 7 3
#>
#> $blue
#> [1] 12 7 3
#>
#> $blue
#> [1] 12 7 3
#>
#> $green
#> [1] 11 6 2
#>
#> $blue
#> [1] 12 7 3
sampled_cols
#> $green
#> [1] 3 5 9
#>
#> $green
#> [1] 3 5 9
#>
#> $green
#> [1] 3 5 9
#>
#> $blue
#> [1] 4 6 10
#>
#> $red
#> [1] 2 4 8
mats <- list()
for(i in seq_along(sampled_rows)){
mats[[i]] <- sampled_rows[[i]] %*% t(sampled_rows[[i]])
}
mats
#> [[1]]
#> [,1] [,2] [,3]
#> [1,] 144 84 36
#> [2,] 84 49 21
#> [3,] 36 21 9
#>
#> [[2]]
#> [,1] [,2] [,3]
#> [1,] 144 84 36
#> [2,] 84 49 21
#> [3,] 36 21 9
#>
#> [[3]]
#> [,1] [,2] [,3]
#> [1,] 144 84 36
#> [2,] 84 49 21
#> [3,] 36 21 9
#>
#> [[4]]
#> [,1] [,2] [,3]
#> [1,] 121 66 22
#> [2,] 66 36 12
#> [3,] 22 12 4
#>
#> [[5]]
#> [,1] [,2] [,3]
#> [1,] 144 84 36
#> [2,] 84 49 21
#> [3,] 36 21 9
Created on 2022-12-04 by the reprex package (v2.0.1)
Finally, there is another case, which is if you don't want to sample colnames as blocks, but instead to take each element randomly from the set of all possible colnames. I don't think this is what you want based on your description.