我正在R
写一个邻接矩阵,如下所示:
neighbours <- array(0, c(100,100))
for (i in 1:100) { neighbours[i,i] = 1 } #reflexive
但后来我注意到class(neighbours)
是double matrix
。用更大的矩阵来占用太多空间。所以我想将类型强制转换为integer
,或者甚至更好,因为它是无向的,logical
。
但是...
> class(neighbours[5])
[1] "numeric"
> class(neighbours[5]) <- "integer"
> class(neighbours[5])
[1] "numeric"
不听我的话!
答案 0 :(得分:9)
最好不要首先将其初始化为数字,但如果你不能这样做,请设置storage.mode
:
R> neighbours <- array(0, c(100,100))
R> for (i in 1:100) { neighbours[i,i] = 1 }
R> str(neighbours)
num [1:100, 1:100] 1 0 0 0 0 0 0 0 0 0 ...
R> storage.mode(neighbours) <- "integer"
R> str(neighbours)
int [1:100, 1:100] 1 0 0 0 0 0 0 0 0 0 ...
R> storage.mode(neighbours) <- "logical"
R> str(neighbours)
logi [1:100, 1:100] TRUE FALSE FALSE FALSE FALSE FALSE ...
答案 1 :(得分:3)
也许我错过了什么,但为什么不直接将它声明为逻辑阵列?
neighbors <- array(FALSE, c(100,100))
diag(neighbors) <- TRUE
比较两者:
> object.size(array(0, c(100,100)))
80200 bytes
> object.size(array(FALSE, c(100,100)))
40200 bytes
编辑:我很想知道为什么逻辑数组每个条目占用4B,但是......
答案 2 :(得分:2)
一个选项是最初用整数0(0L
)填充,然后用整数1替换对角线,(1L
)
m <- matrix(0L, 100, 100)
diag(m) <- 1L
这是在R中创建对角矩阵的更直接方式的一半:
m2 <- diag(1L, 100, 100)
> object.size(m)
40200 bytes
> object.size(m2)
80200 bytes
因此,分配整数矩阵m
然后改变对角线会产生最紧凑的密集矩阵。
答案 3 :(得分:2)
Matrix包中有一个sparseMatrix超类(现在是标准包)。如果你想要一个稀疏的对角矩阵,你可以用
创建它library(Matrix)
Matrix(diag(1,4) , sparse=TRUE)
#---------
4 x 4 sparse Matrix of class "dsCMatrix"
[1,] 1 . . .
[2,] . 1 . .
[3,] . . 1 .
[4,] . . . 1
进一步思考。如果要将矩阵的模式更改为整数,并且不关心它是否保持密集:
> m <- matrix(rnorm(25), 5)
> m[] <- as.integer(m)
# you do need those square-brackets or the structure becomes a dimensionless vector.
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 -1 0 0
[2,] 1 0 0 0 0
[3,] 1 0 0 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 -1 0
然而Gavin评论提出了另一个想法:如果你的目标是表示“邻接”,并且它是一个非常大的样本空间,你可能只想使用sparseMatrix类作为模型,而是使用两列矩阵列中的对数。这并不是sparseMatrices如何保存其行,列和值,但是2列存储模式可能适用于您的问题。请参阅“igraph”包中的工作示例。我认为您的问题可能表示为无向图。