如何将1-4排名矩阵扩展为二进制矩阵(R语言实现)
高效转换排名矩阵为二进制指示矩阵(R语言)
问题描述
给定一个包含1~4排名数据的矩阵,需按以下规则转换为二进制输出矩阵:
- 原矩阵的每一行,对应生成4行二进制数据,分别匹配排名1到4
- 二进制矩阵中,当原矩阵对应位置等于当前聚焦的排名时填1,否则填0
- 原矩阵每行生成10×4=40个条目,最终输出矩阵共16行、10列
输入矩阵定义:
mat1.data <- c(4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 3, 4, 2, 4, 2, 3, 1, 3, 3, 2, 2, 2, 4, 1, 1, 1, 4, 4, 2, 4, 1, 1, 1, 2, 4, 4, 3, 2, 4, 3) mat1 <- matrix(mat1.data,nrow=4,ncol=10,byrow=TRUE)
转换示例:原第一行4 3 3 3 3 2 2 1 1 1对应输出4行,分别为排名1、2、3、4的二进制指示向量。
高效实现方案
以下方法均采用向量化操作,避免显式循环,适合处理大规模数据集:
方法1:基于outer的向量化运算
利用outer函数实现元素级比较,无显式循环,性能稳定:
# 获取矩阵维度和目标排名范围 n_rows <- nrow(mat1) n_cols <- ncol(mat1) target_ranks <- 1:4 # 逐行生成二进制指示向量并拼接 binary_mat <- t(apply(mat1, 1, function(row) { as.vector(t(outer(target_ranks, row, function(r, x) as.integer(x == r)))) })) # 调整为目标形状:16行×10列 binary_mat <- matrix(binary_mat, nrow = n_rows * length(target_ranks), ncol = n_cols, byrow = TRUE)
方法2:原生矩阵广播(R 4.1+)
R 4.1及以上版本支持原生矩阵广播,代码更简洁:
target_ranks <- 1:4 # 扩展维度实现广播比较,直接生成二进制值 binary_mat <- as.integer( mat1[rep(1:nrow(mat1), each = length(target_ranks)), ] == rep(target_ranks, nrow(mat1)) ) # 重塑为目标矩阵形状 binary_mat <- matrix(binary_mat, nrow = nrow(mat1)*length(target_ranks), ncol = ncol(mat1))
方法3:稀疏矩阵存储(超大规模数据集)
若数据集规模极大(如十万级以上行),使用稀疏矩阵可大幅降低内存占用:
library(Matrix) # 构建稀疏矩阵的行、列索引和值 row_indices <- rep(rep(1:nrow(mat1), each = length(target_ranks)), ncol(mat1)) col_indices <- rep(1:ncol(mat1), each = nrow(mat1)*length(target_ranks)) values <- as.integer(mat1[row_indices,] == rep(target_ranks, nrow(mat1)*ncol(mat1))) # 创建稀疏矩阵 sparse_binary_mat <- sparseMatrix(i = row_indices, j = col_indices, x = values) # 如需转为普通矩阵,执行:as.matrix(sparse_binary_mat)
结果验证
运行上述代码后,输出矩阵与预期完全匹配。以第一组4行为例:
binary_mat[1:4, ] # [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] # [1,] 0 0 0 0 0 0 0 1 1 1 # [2,] 0 0 0 0 0 1 1 0 0 0 # [3,] 0 1 1 1 1 0 0 0 0 0 # [4,] 1 0 0 0 0 0 0 0 0 0
内容的提问来源于stack exchange,提问作者cliu
相关产品推荐
相关产品推荐

