如何用布尔矩阵对另一矩阵按行进行子集化?
布尔矩阵筛选对应矩阵元素的解决方案
嘿,我来帮你搞定这个需求!你想要根据布尔矩阵里的TRUE位置,提取另一个矩阵对应行的对应列元素对吧?其实在R里有挺简洁的实现方式,不用写复杂的循环,还能封装成函数方便复用。
先看你给出的示例数据,我先把代码整理好:
set.seed(0) knl <- c(FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) A = matrix(knl, nrow=3, ncol=6, byrow=TRUE) B = matrix(rnorm(18),3,6)
这里A是3行6列的布尔矩阵,每行里的TRUE就是我们要从B对应行提取的列位置。
方法1:用lapply按行提取(推荐)
这种写法直观又高效,直接遍历每一行的索引,提取对应位置的元素:
# 提取每行的目标元素,返回列表(每个元素对应一行的结果) result_list <- lapply(1:nrow(A), function(i) B[i, A[i, ]])
运行后result_list里的每个元素就是B对应行中,A里为TRUE的列的元素。比如你的示例里每行只有1个TRUE,所以列表里每个元素是单个数值。
方法2:用apply函数处理
也可以用apply对布尔矩阵的每一行做处理:
result_list <- apply(A, 1, function(row_bool, data_mat) { data_mat[which(row_bool), ] }, data_mat = B)
这里MARGIN=1表示按行处理,把每行的布尔值和数据矩阵B传入匿名函数,筛选出对应元素。
把结果转成矩阵(如果每行筛选结果长度一致)
如果你的布尔矩阵每行的TRUE数量都相同(比如示例里每行1个),可以把列表转成矩阵:
result_matrix <- do.call(rbind, result_list)
封装成可复用的函数
如果你需要经常用这个功能,可以把逻辑封装成函数,就像你提到的fn:
fn <- function(bool_matrix, data_matrix) { # 先检查两个矩阵维度是否一致 if (!all(dim(bool_matrix) == dim(data_matrix))) { stop("布尔矩阵和数据矩阵的行列数必须一致!") } lapply(1:nrow(bool_matrix), function(i) data_matrix[i, bool_matrix[i, ]]) } # 调用函数 my_result <- fn(A, B)
这个函数还加了维度检查,避免传入不匹配的矩阵导致错误。
内容的提问来源于stack exchange,提问作者jovianlynxdroid
相关产品推荐
相关产品推荐

