如何快速有效地计算 R 中由零和一组成的大型矩阵

How to calculate a large matrix of zeros and ones in R quickly and efficiently

我使用 R 已有一段时间了,但我不太擅长优化我的代码以提高性能。

给定一个长度为 t 的向量 Y,我试图生成一个 t 阶方阵,因此它的第 i 行对应于$1_{Y_i < Y_j}$ 全部 j = 1, 2, ..., t。所以这是一个0 / 1的二进制矩阵。

Y <- matrix(0, length(t), length(t))
for(i in 1:length(t))  Y[i, ] <- (t[i] <= t)

但是,我认为这不是最有效的方法,主要是看对象的大小。它与密集矩阵的大小相同(以字节为单位)。我的目标是将其扩展到大 t,但我相信这样一个矩阵的计算速度和存储 space 会花费太长时间。有没有更快更有效的方法来存储和计算这个矩阵?

如果我没理解错的话,我们可以使用:

outer(t, t, "<=") + 0L
## operator `"<="` returns TRUE / FALSE logical, 
## add an integer 0 to make a 0 / 1 binary integer matrix

让我们快速测试一下,与您的参考 for 循环进行比较。

set.seed(0); t <- runif(5)  ## reproducible data

outer(t, t, "<=") + 0L
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    0    0    0    1
#[2,]    1    1    1    1    1
#[3,]    1    0    1    1    1
#[4,]    1    0    0    1    1
#[5,]    0    0    0    0    1

Y <- matrix(0, nrow=length(t), ncol=length(t))
for(i in 1:length(t)) {
  Y[i, ] <- t[i] <= t
}

Y
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    0    0    0    1
#[2,]    1    1    1    1    1
#[3,]    1    0    1    1    1
#[4,]    1    0    0    1    1
#[5,]    0    0    0    0    1

我们得到了相同的结果。宾果!!


注:

有人看过这个答案的编辑历史。给出了一个带有sparseMatrix的方法。我最初认为使用稀疏矩阵和列旋转会提高效率,但没有。基准测试显示 outer 快 6 倍或更多倍。因此,虽然我很难过,但我不得不把我的大部分答案都扔掉。