I am making a figure that has the following layout matrix.
(Individual_Layout_Matrix <- matrix(c(1, 1, 2, 3, 4, 4), byrow = TRUE, ncol = 2))
# [,1] [,2]
# [1,] 1 1
# [2,] 2 3
# [3,] 4 4
This figure has a blank plot at the top for an overall figure title, two side-by-side plots, and a blank plot at the bottom for a legend.
I have a study with multiple levels of multiple factors and I want to create panels that follow this format where each panel contains a figure formatted exactly like my Individual_Layout_Matrix
object above. (Actually, I want to create an algorithm that can handle other types of cases beyond mine too.)
The final figure I want to make will have the following layout matrix, with each panel in this layout matrix itself being comprised of my 4-panel figure from above.
(Overall_Layout_Matrix <- matrix(c(1, 1, 2, 2, 8, 3, 4, 5, 6, 8, 0, 7, 7, 0, 8), byrow = TRUE, ncol = 5))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 2 2 8
# [2,] 3 4 5 6 8
# [3,] 0 7 7 0 8
Therefore, if each plot is generated in succession and placed in the final plot layout matrix in order, the final layout matrix will have the following form.
(Final_Layout_Matrix <- matrix(c(1, 1, 1, 1, 5, 5, 5, 5, 29, 29, 2, 2, 3, 3, 6, 6, 7, 7, 29, 29, 4, 4, 4, 4, 8, 8, 8, 8, 29, 29, 9, 9, 13, 13, 17, 17, 21, 21, 30, 31, 10, 11, 14, 15, 18, 19, 22, 23, 30, 31, 12, 12, 16, 16, 20, 20, 24, 24, 30, 31, 0, 0, 25, 25, 25, 25, 0, 0, 32, 32, 0, 0, 26, 26, 27, 27, 0, 0, 32, 32, 0, 0, 28, 28, 28, 28, 0, 0, 32, 32), byrow = TRUE, ncol = 10))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 1 1 1 5 5 5 5 29 29
# [2,] 2 2 3 3 6 6 7 7 29 29
# [3,] 4 4 4 4 8 8 8 8 29 29
# [4,] 9 9 13 13 17 17 21 21 30 31
# [5,] 10 11 14 15 18 19 22 23 30 31
# [6,] 12 12 16 16 20 20 24 24 30 31
# [7,] 0 0 25 25 25 25 0 0 32 32
# [8,] 0 0 26 26 27 27 0 0 32 32
# [9,] 0 0 28 28 28 28 0 0 32 32
I have two questions.
First, how can I write a function that will take Individual_Layout_Matrix
and Overall_Layout_Matrix
as inputs and provide Final_Layout_Matrix
as the output?
Second, how can I check to see that the Overall_Layout_Matrix
provided is an appropriate one? For example, each unique number in the Overall_Layout_Matrix
must be together and rectangular in shape - for example, something like
matrix(c(1, 1, 1, 2, 2, 3, 4, 4, 5, 4, 4, 4), byrow = T, ncol = 3)
# [,1] [,2] [,3]
# [1,] 1 1 1
# [2,] 2 2 3
# [3,] 4 4 5
# [4,] 4 4 4
won't work because the number 4
does not appear in a standalone rectangle.
A messy piece of code:
layout_augment <- function(x, y) {
y_dim <- dim(y)
y_max <- max(y)
mat <- res <- kronecker(x, array(1, y_dim))
for(i in unique(x[x != 0])) {
z_ind <- which(mat == i, arr.ind = TRUE)
z_dim <- apply(z_ind, 2, \(col) diff(range(col)) + 1)
r <- z_dim / y_dim
y2 <- y[rep(seq_len(y_dim[1]), each = r[1]),
rep(seq_len(y_dim[2]), each = r[2])] + (i-1)*y_max
if(nrow(z_ind) != length(y2)) {
stop("number ", i, " does not appear in a standalone rectangle")
}
res[z_ind] <- y2
}
return(res)
}
layout_augment(Overall_Layout_Matrix, Individual_Layout_Matrix)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 1 1 1 5 5 5 5 29 29
# [2,] 2 2 3 3 6 6 7 7 29 29
# [3,] 4 4 4 4 8 8 8 8 29 29
# [4,] 9 9 13 13 17 17 21 21 30 31
# [5,] 10 11 14 15 18 19 22 23 30 31
# [6,] 12 12 16 16 20 20 24 24 30 31
# [7,] 0 0 25 25 25 25 0 0 32 32
# [8,] 0 0 26 26 27 27 0 0 32 32
# [9,] 0 0 28 28 28 28 0 0 32 32
Bad_Layout_Matrix <- matrix(c(1, 1, 1, 2, 2, 3, 4, 4, 5, 4, 4, 4), byrow = TRUE, ncol = 3)
layout_augment(Bad_Layout_Matrix, Individual_Layout_Matrix)
Error in layout_augment(Bad_Layout_Matrix, Individual_Layout_Matrix) :
number 4 does not appear in a standalone rectangle