使用包含行名和列名的索引向量将值添加到矩阵

dsc*_*ffy 6 r matrix sparse-matrix indices

假设我有一个非常大的稀疏数据矩阵,但我只想看一下它的样本,使它更稀疏.假设我还有一个三元数据框,包括数据的行/列/值列(从csv文件导入).我知道我可以使用库(Matrix)的sparseMatrix()函数来创建稀疏矩阵

sparseMatrix(i=df$row,j=df$column,x=df$value)
Run Code Online (Sandbox Code Playgroud)

但是,由于我的值,我最终得到了一个稀疏矩阵,其中包含数百万行数万列(其中大多数都是空的,因为我的子集排除了大多数行和列).所有这些零行和列最终都会扭曲我的一些函数(例如,采用聚类 - 当一个原点甚至不是有效点时,我最终会得到一个包含原点的聚类).我想执行相同的操作,但使用i和j作为rownames和colnames.我已经尝试创建一个密集的矢量,采样到最大尺寸并使用添加值

denseMatrix <- matrix(0,nrows,ncols,dimnames=c(df$row,df$column))
denseMatrix[as.character(df$row),as.character(df$column)]=df$value
Run Code Online (Sandbox Code Playgroud)

(实际上我一直把它设置为等于1,因为我对这种情况下的值不感兴趣)但是我发现它填充了整个矩阵,因为它需要所有行和列的交叉而不仅仅是row1*col1,row2*col2 ...有没有人知道如何完成我想要做的事情?或者我可以填写一个稀疏矩阵并简单地以某种方式丢弃所有零行和列以将其自身压缩为更密集的形式(但我想保留一些参考回原始行和列号)我感谢任何建议!

这是一个例子:

> rows<-c(3,1,3,5)
> cols<-c(2,4,6,6)
> mtx<-sparseMatrix(i=rows,j=cols,x=1)
> mtx
5 x 6 sparse Matrix of class "dgCMatrix"

[1,] . . . 1 . .
[2,] . . . . . .
[3,] . 1 . . . 1
[4,] . . . . . .
[5,] . . . . . 1
Run Code Online (Sandbox Code Playgroud)

我想摆脱colums 1,3和5以及第2行和第4行.这是一个非常简单的例子,但想象一下,如果没有行号1,3和5,它们分别是1000,3000和5000.然后它们之间会有更多的空行.这是当我使用具有命名行/列的密集矩阵时发生的情况

> dmtx<-matrix(0,3,3,dimnames=list(c(1,3,5),c(2,4,6)))
> dmtx
  2 4 6
1 0 0 0
3 0 0 0
5 0 0 0
> dmtx[as.character(rows),as.character(cols)]=1
> dmtx
  2 4 6
1 1 1 1
3 1 1 1
5 1 1 1
Run Code Online (Sandbox Code Playgroud)

Aar*_*ica 5

您的代码几乎可以工作,您只需要将cbind行名称和列名称组合在一起即可。然后将所得矩阵的每一行视为一对,而不是分别处理行和列。

> dmtx <- matrix(0,3,3,dimnames=list(c(1,3,5),c(2,4,6)))
> dmtx[cbind(as.character(rows),as.character(cols))] <- 1
> dmtx
  2 4 6
1 0 1 0
3 1 0 1
5 0 0 1
Run Code Online (Sandbox Code Playgroud)

如果您使用因子,这可能会更快。

> rowF <- factor(rows)
> colF <- factor(cols)
> dmtx <- matrix(0, nlevels(rowF), nlevels(colF), 
                 dimnames=list(levels(rowF), levels(colF)))
> dmtx[cbind(rowF,colF)] <- 1
> dmtx
  2 4 6
1 0 1 0
3 1 0 1
5 0 0 1
Run Code Online (Sandbox Code Playgroud)

您还可以在对 的调用中使用这些因素sparseMatrix

> sparseMatrix(i=as.integer(rowF), j=as.integer(colF), x=1,
+              dimnames = list(levels(rowF), levels(colF)))
3 x 3 sparse Matrix of class "dgCMatrix"
  2 4 6
1 . 1 .
3 1 . 1
5 . . 1
Run Code Online (Sandbox Code Playgroud)

请注意,其他解决方案之一可能更快;如果数据很多,转换为因子可能会很慢。


Rei*_*son 4

当您说“删除”某些列/行时,您的意思是这样的:

> mtx[-c(2,4), -c(1,3,5)]
3 x 3 sparse Matrix of class "dgCMatrix"

[1,] . 1 .
[2,] 1 . 1
[3,] . . 1
Run Code Online (Sandbox Code Playgroud)

子集设置有效,所以您只需要一种方法来找出哪些行和列是空的?如果这是正确的,那么您可以使用colSums()和 ,因为MatrixrowSums()包已经增强了它们,以便为稀疏矩阵提供适当的方法。这应该在操作过程中保持稀疏性

> dimnames(mtx) <- list(letters[1:5], LETTERS[1:6])
> mtx[which(rowSums(mtx) != 0), which(colSums(mtx) != 0)]
3 x 3 sparse Matrix of class "dgCMatrix"
  B D F
a . 1 .
c 1 . 1
e . . 1
Run Code Online (Sandbox Code Playgroud)

或者,也许更安全

> mtx[rowSums(mtx) != 0, colSums(mtx) != 0]
3 x 3 sparse Matrix of class "dgCMatrix"
  B D F
a . 1 .
c 1 . 1
e . . 1
Run Code Online (Sandbox Code Playgroud)