如何从维名称列表中创建稀疏矩阵?
假设您在数据框中有此矩阵边缘列表:
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
谢谢,马丁,指点我这个方向。
答案 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
参数比之后单独设置colnames
和rownames
更有效。
答案 1 :(得分:1)
我认为你知道你可以做一些简单的事情:
for (i in 1:nrow(foo)) bar[as.character(c(foo[i,1])),c(foo[i,2])] <- foo[i,3]
但是如果你想更有效地使用Matrix,你可能需要编写自己的函数来分配它。类似的东西:
from
和to
列转换为以您想要的任何方式排序的因素foo
排序from
然后to
(如果您不能保证这已经成立)并删除重复项foo@i
设为bar$from-1
foo@p
设为bar$to-1 + length(colnames(bar)) * (bar$from-1)
foo@x
设为bar$weight