对角线上是1的矩阵

5

假设我有以下矩阵mat,它是一个二进制指示器矩阵:

mat<-matrix(c(1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1), byrow=T, nrow=3)

> mat
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1    0    0    0    0
[2,]    0    0    1    1    0    0
[3,]    0    0    0    0    1    1

这个矩阵只有3行。我需要创建一个有10000行的矩阵,并且具有对角线上1对1的相同模式。 例如,对于5行,我期望得到一个5 x 10的矩阵:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    0    0    0    0    0    0    0     0
[2,]    0    0    1    1    0    0    0    0    0     0
[3,]    0    0    0    0    1    1    0    0    0     0
[4,]    0    0    0    0    0    0    1    1    0     0
[5,]    0    0    0    0    0    0    0    0    1     1

有没有人知道一个简单的方法来实现这个?非常感谢。

将单位矩阵复制每一列。 - smci
5个回答

4
这是一个稀疏矩阵,因此最好引用非零条目:这将节省RAM,并使自动生成矩阵更容易。每个条目都被索引为(i,j,x),分别表示行、列和值。假设您有N(比如N = 10)行要填充,那么每行产生2个条目(在下面的代码中由索引);每列仅使用一次,因此有2*N个唯一的列值。每个非零条目为1。生成此代码的代码如下:
N = 10
i = rep(1:N, each = 2)
j = 1:(2*N)
v = 1

library(Matrix)
mat = sparseMatrix(i = i, j = j, x = v)

生成的矩阵为:
> mat
10 x 20 sparse Matrix of class "dgCMatrix"

 [1,] 1 1 . . . . . . . . . . . . . . . . . .
 [2,] . . 1 1 . . . . . . . . . . . . . . . .
 [3,] . . . . 1 1 . . . . . . . . . . . . . .
 [4,] . . . . . . 1 1 . . . . . . . . . . . .
 [5,] . . . . . . . . 1 1 . . . . . . . . . .
 [6,] . . . . . . . . . . 1 1 . . . . . . . .
 [7,] . . . . . . . . . . . . 1 1 . . . . . .
 [8,] . . . . . . . . . . . . . . 1 1 . . . .
 [9,] . . . . . . . . . . . . . . . . 1 1 . .
[10,] . . . . . . . . . . . . . . . . . . 1 1

只需使用上面的代码并设置N = 10000,您就可以得到矩阵。

额外的好处是:您所需的矩阵(N = 1E5)仅消耗321424字节。相比之下,一个标准的10K x 20K大小的密集矩阵将使用数字(即8字节)条目占用1.6GB。正如在《星际之门》中所说的那样:这似乎是一种可怕的浪费空间,对吧?


1

当你没有提供足够的元素来填充矩阵时,它们将被循环使用:如果你提供了两个 1 和 n 个 0(第一行和第二行前两个元素),你将得到所需的矩阵。

n <- 5
matrix( 
  c(1,1,rep(0,2*n)), 
  byrow=TRUE, nr=n, nc=2*n 
)

非常感谢您的迅速回答。我的问题定义不清楚,我已经进行了编辑。最好的祝福。 - user1182757
@user1182757:我已经编辑了我的答案以匹配你的问题。 - Vincent Zoonekynd

1

除非您打算在矩阵中填充许多其他值,否则您可能需要使用迭代器的稀疏矩阵解决方案。话虽如此,这里有一种可爱的方法来生成一个非稀疏版本的矩阵:

double_diag <- function(n)
{
  matrix(rep(diag(n), each = 2), byrow = TRUE, nrow = n)
}
double_diag(5)

1

@VincentZooneKynd有一个不错的解决方案,但是它会引发一个警告。这里有一个避免警告的变体:

n <- 5
matrix(rep(c(1,1,rep(0,2*n)), len=2*n*n), n, byrow=TRUE)

0

技巧:

> n <- 5
> t(model.matrix(~0+gl(n,2)))[,]
          1 2 3 4 5 6 7 8 9 10
gl(n, 2)1 1 1 0 0 0 0 0 0 0  0
gl(n, 2)2 0 0 1 1 0 0 0 0 0  0
gl(n, 2)3 0 0 0 0 1 1 0 0 0  0
gl(n, 2)4 0 0 0 0 0 0 1 1 0  0
gl(n, 2)5 0 0 0 0 0 0 0 0 1  1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接