首页 > 解决方案 > 从稀疏矩阵转换为密集矩阵而不丢失暗名?

问题描述

将稀疏Matrix对象(来自Matrix包)转换为普通的旧 base-R 密集matrix对象似乎会丢失行/列名称。

m <- matrix(0, 3,3, dimnames = list(LETTERS[1:3], LETTERS[1:3]))
dimnames(m)
## [[1]]
## [1] "A" "B" "C"
## 
## [[2]]
## [1] "A" "B" "C"

转换aMatrix很好:

dimnames(M <- Matrix::Matrix(m))
## [[1]]
## [1] "A" "B" "C"
## [[2]]
## [1] "A" "B" "C"

但是转换回来似乎会丢失行/列名称:

dimnames(as.matrix(M))
## NULL
dimnames(as(M, "matrix"))
## NULL

我知道我可以通过存储暗名然后将它们附加到新对象来解决它(见下文),但我觉得我不应该这样做......我是否错过了一种透明/更好的制作方法转换,或者在进行此转换时不应保留名的逻辑原因?

## workaround/hack
dn <- dimnames(m)
m2 <- as.matrix(M)
dimnames(m2) <- dn

澄清一下,我想处理M已经定义m尚未定义的情况(即在保持其属性不变的情况m[] <-下替换内容的旧技巧m似乎不起作用......)

标签: rmatrixsparse-matrix

解决方案


[更新 1:错误报告] [更新 2:补丁]

这里的丢失[dD]imnames似乎是 中的一个错误Matrix,至少在所讨论的特定子类的实现"Matrix"中,即"ddiMatrix"(参见?`ddiMatrix-class`)。

library("Matrix")
M <- Matrix(0, 3L, 3L, dimnames = list(LETTERS[1:3], LETTERS[1:3]))
M
3 x 3 diagonal matrix of class "ddiMatrix"
  A B C
A 0 . .
B . 0 .
C . . 0

有一种强制 from "ddiMatrix"to的方法"matrix",当你这样做时会调用它,但正如你观察到的那样as(M, "matrix"),它不会保留。[dD]imnames

selectMethod("coerce", signature(from = "ddiMatrix", to = "matrix"))
Method Definition:

function (from, to = "matrix", strict = TRUE) 
base::diag(if (from@diag == "U") as1(from@x) else from@x, nrow = from@Dim[1])
<bytecode: 0x11e7dc068>
<environment: namespace:Matrix>

Signatures:
        from        to      
target  "ddiMatrix" "matrix"
defined "ddiMatrix" "matrix"

"ddiMatrix"您可以使用从to的中间强制来解决该错误"dgCMatrix",这是一种更通用且更仔细实现的稀疏数字矩阵类(请参阅 参考资料?`dgCMatrix-class`)。"ddiMatrix"从to "dgCMatrix"to "matrix" do preserve的强制[dD]imnames

MM <- as(M, "dgCMatrix")
MM
3 x 3 sparse Matrix of class "dgCMatrix"
  A B C
A . . .
B . . .
C . . .
m <- as(MM, "matrix")
m
  A B C
A 0 0 0
B 0 0 0
C 0 0 0

或者干脆m <- as(as(M, "dgCMatrix"), "matrix")

需要明确的是,您的方法既更快更透明。我提出这个主要是为了揭露这个错误影响"ddiMatrix"但不是所有类的稀疏数字矩阵在Matrix. 如果您的用例实际上不需要"ddiMatrix",那么您不必担心保护[dD]imnames自己。

FWIW,在与Matrix胁迫作斗争时,我发现它有助于:

  1. 用来showClass("Matrix")提醒自己子类的继承结构"Matrix"
  2. 查阅?`<classname>-class`(1) 中报告的类及其插槽的可读描述。
  3. 用于selectMethod("coerce", signature(from=, to=))查找实际调用的方法as(不过,由于强制通常在 C 中实现,selectMethod因此除了告诉我要搜索的内容之外,结果可能没有帮助Matrix/src)。

推荐阅读