R:维名称列表中的稀疏矩阵

时间:2014-04-16 11:16:26

标签: r list matrix sparse-matrix

如何从维名称列表中创建稀疏矩阵?

假设您在数据框中有此矩阵边缘列表:

  from to weight
1    4  a      1
2    5  b      2
3    6  c      3

可以像这样创建:

from <- factor(c(4:6))
to <- c("a", "b", "c")
weight <- c(1:3)
foo <- data.frame(from, to, weight)

可以通过首先创建一个填充0的空矩阵,命名行和列,然后填充以下值来创建矩阵:

bar <- matrix(
  0,
  nrow = length(unique(foo$from)),
  ncol = length(unique(foo$to)),
  dimnames = list(levels(foo$from), levels(foo$to))
)
bar[as.matrix(foo[,1:2])] <- foo[,3]

结果如下:

  a b c
4 1 0 0
5 0 2 0
6 0 0 3

如何创建稀疏矩阵?

解决方案

一种优雅的方法是使用Matrix包,它需要使用factors的整数值:

bar_sparse <- sparseMatrix(
  i = as.numeric(foo$from),
  j = as.numeric(foo$to),
  x = foo$weight,
  dimnames = list(levels(foo$from), levels(foo$to))
)

我们走了:

  a b c
4 1 . .
5 . 2 .
6 . . 3

谢谢,马丁,指点我这个方向。

2 个答案:

答案 0 :(得分:3)

作为Matrix包的维护者:在构造中允许对sparseMatrix对象使用dimnames, 对于甚至重要的列名,特别是例如对于稀疏模型矩阵(在glmnet等)。 但出于效率原因(部分缺乏使用案例,因此&#34;还没有 实现&#34;)它们并不总是在矩阵乘法中传播,例如IIRC。

这个&#34;半气馁的主要原因&#34;支持是稀疏矩阵在nrow(.) * ncol(.)大的意义上非常大时特别重要的事实。 在这种情况下,携带(和复制!!)数十万行(和列)名称是昂贵的。

在所有这些警告之后,当然我承认你已经提出了一个非常有效的问题,你现在可能没有选择,确实需要使用行和列名称来代替整数指数。

是的,你(几乎)是对的: 使用

M <- Matrix(0, n,m, dimnames=....)
for(i in ...)
  for(j in ...)
        M[i,j] <- ...
对于sparseMatrix个对象(即从sparseMatrix继承的所有Matrix对象),

从不是一个好主意。 相反,使用sparseMatrix(...., dimnames = ..) ..注意使用dimnames参数比之后单独设置colnamesrownames更有效。

答案 1 :(得分:1)

我认为你知道你可以做一些简单的事情:

for (i in 1:nrow(foo)) bar[as.character(c(foo[i,1])),c(foo[i,2])] <- foo[i,3]

但是如果你想更有效地使用Matrix,你可能需要编写自己的函数来分配它。类似的东西:

  • fromto列转换为以您想要的任何方式排序的因素
  • foo排序from然后to(如果您不能保证这已经成立)并删除重复项
  • 创建具有正确尺寸的空白矩阵
  • foo@i设为bar$from-1
  • foo@p设为bar$to-1 + length(colnames(bar)) * (bar$from-1)
  • foo@x设为bar$weight