R语言逻辑对称矩阵按全TRUE连通规则分块并标注同块编号
分块标注实现代码
你可以根据矩阵大小选择无依赖的基础R版本,或者适合大矩阵的igraph高效版本:
1. 输入矩阵构造
MAT <- matrix(data = c(rep(TRUE, 9), rep(FALSE, 3), rep(TRUE, 3), FALSE, rep(TRUE, 3), rep(FALSE, 2), TRUE, FALSE, rep(TRUE, 2), FALSE, TRUE, FALSE, rep(TRUE, 3), FALSE, rep(TRUE, 4)), nrow = 6) # 给行列设置中文名称方便识别 colnames(MAT) <- paste0("列", 1:ncol(MAT)) rownames(MAT) <- paste0("行", 1:nrow(MAT))
2. 基础R无依赖实现
不需要安装额外包,直接运行即可得到每列对应的分块编号:
n_col <- ncol(MAT) # 初始化分块编号向量 block_label <- rep(NA, n_col) current_num <- 1 for (idx in 1:n_col) { if (is.na(block_label[idx])) { # 筛选当前未分配、和当前列所有关联值全为TRUE的候选列 unassigned <- which(is.na(block_label)) candidate_cols <- unassigned[apply(MAT[, unassigned, drop = FALSE], 2, function(col) all(MAT[idx, ] & col))] # 校验候选列之间两两关联是否全为TRUE is_valid <- TRUE if (length(candidate_cols) > 1) { pair_mat <- combn(candidate_cols, 2) for (p in 1:ncol(pair_mat)) { if (!MAT[pair_mat[1,p], pair_mat[2,p]]) { is_valid <- FALSE break } } } # 分配分块编号 if (is_valid) { block_label[candidate_cols] <- current_num } else { block_label[idx] <- current_num } current_num <- current_num + 1 } } # 输出结果:键为列名,值为对应分块编号 print(block_label)
3. igraph高效实现(适合大尺寸矩阵)
基于图论极大团检测逻辑,处理大矩阵效率远高于基础循环:
# 首次使用需先安装依赖包 # install.packages("igraph") library(igraph) # 以逻辑矩阵为邻接矩阵构建无向图 g <- graph_from_adjacency_matrix(MAT, mode = "undirected", diag = FALSE) # 提取所有极大团:团内任意两点都有边(即关联值为TRUE) cliques <- max_cliques(g) n_col <- ncol(MAT) block_label <- rep(NA, n_col) current_num <- 1 # 给无重叠的极大团分配编号 for (cliq in cliques) { node_idx <- as.integer(cliq) if (all(is.na(block_label[node_idx]))) { block_label[node_idx] <- current_num current_num <- current_num + 1 } } # 剩余无匹配的列单独成块 block_label[is.na(block_label)] <- current_num:(current_num + sum(is.na(block_label)) - 1) # 输出结果 names(block_label) <- colnames(MAT) print(block_label)
结果说明
运行代码得到的block_label向量中,数值相同的列属于同一分块,完全匹配要求规则:
- 同一分块内任意两列的关联值全为TRUE
- 存在FALSE关联的列不会被划分到同一块
- 无匹配列自动独立成块
内容的提问来源于stack exchange,提问作者Achille Nyouma
相关产品推荐
相关产品推荐

