R绘图布局矩阵复用:生成函数与有效性验证问询
多面板图形布局矩阵生成与验证问题
我正在制作一个包含如下布局矩阵的图形:
(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
该图形顶部是用于总标题的空白绘图,中间为两个并排绘图,底部是用于图例的空白绘图。
我的研究涉及多因子多水平,需要创建遵循该格式的面板,每个面板包含上述4部分结构的图形,且算法需适配更多场景。
最终图形的布局矩阵如下,其中每个面板由上述4部分图形组成:
(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
按顺序生成并放置绘图后,最终布局矩阵形式如下:
(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
问题1:编写函数生成最终布局矩阵
如何编写函数,以Individual_Layout_Matrix和Overall_Layout_Matrix为输入,输出Final_Layout_Matrix?
实现逻辑
核心是将全局布局矩阵的每个非0单元格,替换为对应的个体布局矩阵,并对数值重新编号,同时保留全局共用区域的独立编号:
- 统计个体布局矩阵的非0唯一值数量,作为每个面板的元素数;
- 遍历全局矩阵的每个单元格,将非0单元格替换为编号偏移后的个体矩阵;
- 为全局共用区域(示例中的8、29等)分配独立的连续编号。
R语言实现代码
generate_final_layout <- function(indiv_mat, overall_mat) { # 提取个体矩阵的非0唯一值并排序 indiv_vals <- sort(unique(indiv_mat[indiv_mat != 0])) n_indiv <- length(indiv_vals) # 提取全局矩阵的非0唯一值 overall_vals <- unique(overall_mat[overall_mat != 0]) # 区分面板值和全局共用值 panel_vals <- overall_vals[overall_vals %in% seq(length(overall_vals))] global_vals <- setdiff(overall_vals, panel_vals) # 计算最终矩阵的维度 final_rows <- nrow(indiv_mat) * nrow(overall_mat) final_cols <- ncol(indiv_mat) * ncol(overall_mat) final_mat <- matrix(0, nrow = final_rows, ncol = final_cols) # 填充面板区域 for (i in seq(nrow(overall_mat))) { for (j in seq(ncol(overall_mat))) { ov_val <- overall_mat[i, j] if (ov_val == 0 || ov_val %in% global_vals) next # 计算当前块在最终矩阵中的位置 row_range <- ((i-1)*nrow(indiv_mat) + 1):(i*nrow(indiv_mat)) col_range <- ((j-1)*ncol(indiv_mat) + 1):(j*ncol(indiv_mat)) # 替换个体矩阵的编号并填充 block <- indiv_mat block[block != 0] <- (ov_val - 1)*n_indiv + block[block != 0] final_mat[row_range, col_range] <- block } } # 填充全局共用区域 next_val <- max(final_mat[final_mat != 0]) + 1 for (gv in global_vals) { for (i in seq(nrow(overall_mat))) { for (j in seq(ncol(overall_mat))) { if (overall_mat[i, j] != gv) next row_range <- ((i-1)*nrow(indiv_mat) + 1):(i*nrow(indiv_mat)) col_range <- ((j-1)*ncol(indiv_mat) + 1):(j*ncol(indiv_mat)) final_mat[row_range, col_range] <- next_val } } next_val <- next_val + 1 } return(final_mat) } # 测试函数 indiv_mat <- matrix(c(1,1,2,3,4,4), byrow=T, ncol=2) overall_mat <- matrix(c(1,1,2,2,8,3,4,5,6,8,0,7,7,0,8), byrow=T, ncol=5) final_mat <- generate_final_layout(indiv_mat, overall_mat) print(final_mat)
问题2:验证布局矩阵的合规性
如何验证提供的Overall_Layout_Matrix是否合规?要求矩阵中每个唯一数值需连续分布且呈矩形,如下示例因数值4未形成独立矩形而不符合要求:
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
验证逻辑
对每个唯一非0值,检查其占据的区域是否为完整矩形:
- 获取当前值的所有行、列索引;
- 计算该值的最小/最大行、列,确定理论矩形范围;
- 检查该矩形范围内的所有单元格是否均为当前值,若存在其他值则不合规。
R语言实现代码
validate_layout_matrix <- function(mat) { unique_vals <- unique(mat[mat != 0]) for (val in unique_vals) { # 获取当前值的所有位置 pos <- which(mat == val, arr.ind = TRUE) min_r <- min(pos[,1]) max_r <- max(pos[,1]) min_c <- min(pos[,2]) max_c <- max(pos[,2]) # 提取理论矩形区域 rect_area <- mat[min_r:max_r, min_c:max_c] # 检查区域内是否全为当前值 if (any(rect_area != val)) { message(sprintf("布局矩阵不合规:值%d的区域不是完整矩形", val)) return(FALSE) } } message("布局矩阵合规") return(TRUE) } # 测试合规矩阵 valid_mat <- matrix(c(1,1,2,2,8,3,4,5,6,8,0,7,7,0,8), byrow=T, ncol=5) validate_layout_matrix(valid_mat) # 返回TRUE # 测试不合规矩阵 invalid_mat <- matrix(c(1,1,1,2,2,3,4,4,5,4,4,4), byrow=T, ncol=3) validate_layout_matrix(invalid_mat) # 返回FALSE并提示错误
内容的提问来源于stack exchange,提问作者David Moore
相关产品推荐
相关产品推荐

