矩阵的哪些行等于某个向量 [英] Which lines of a matrix are equal to a certain vector
问题描述
我有一段代码搜索矩阵 boxes
的哪些行等于给定的向量 x
.这段代码使用了apply
函数,不知道能不能进一步优化一下?
I have a piece of code searching which lines of a matrix boxes
are equal to a given vector x
. This codes uses the apply
function, and i wonder if it can be optimized more ?
x = floor(runif(4)*10)/10
boxes = as.matrix(do.call(expand.grid, lapply(1:4, function(x) {
seq(0, 1 - 1/10, length = 10)
})))
# can the following line be more optimised ? :
result <- which(sapply(1:nrow(boxes),function(i){all(boxes[i,] == x)}))
我自己没有设法摆脱 apply
功能,但也许你会有比我更好的想法:)
I did not manage to get rid of the apply
function myself but maybe you'll have better ideas than me :)
推荐答案
一个选项是 which(colSums(t(boxes) == x) == ncol(boxes))
.
向量是按列循环的,所以我们需要在用 ==
与 x
进行比较之前转置 boxes
.然后我们可以选择 which
列(转置行)具有 ncol(boxes)
的总和,即所有 TRUE
值.
Vectors are recycled column-wise, so we need to transpose boxes
before comparing to x
with ==
. Then we can pick which
column (transposed row) has a sum of ncol(boxes)
, i.e. all TRUE
values.
这是这个(可能不具有代表性)示例的基准
Here's a benchmark for this (possibly not representative) example
Irnv <- function() which(sapply(1:nrow(boxes),function(i){all(boxes[i,] == x)}))
ICT <- function() which(colSums(t(boxes) == x) == ncol(boxes))
RS <- function() which(rowSums(mapply(function(i, j) boxes[, i] == j, seq_len(ncol(boxes)), x)) == length(x))
RS2 <- function(){
boxes <- data.frame(boxes)
which(rowSums(mapply(`==`, boxes, x)) == length(x))
}
akrun <- function() which(rowSums((boxes == x[col(boxes)])) == ncol(boxes))
microbenchmark(Irnv(), ICT(), RS(), RS2(), akrun())
# Unit: microseconds
# expr min lq mean median uq max neval
# Irnv() 19218.470 20122.2645 24182.2337 21882.8815 24949.1385 66387.719 100
# ICT() 300.308 323.2830 466.0395 342.3595 430.1545 7878.978 100
# RS() 566.564 586.2565 742.4252 617.2315 688.2060 8420.927 100
# RS2() 698.257 772.3090 1017.0427 842.2570 988.9240 9015.799 100
# akrun() 442.667 453.9490 579.9102 473.6415 534.5645 6870.156 100
这篇关于矩阵的哪些行等于某个向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!