【问题标题】:R: Sparse matrix from list of dimension namesR:来自维度名称列表的稀疏矩阵
【发布时间】:2014-05-31 05:32:57
【问题描述】:

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

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

  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

感谢 Martin,您为我指明了这个方向。

【问题讨论】:

  • 虽然与从 dimnames 重新构建标题不同,但您可以使用 xtabs 从加权边缘列表中获取稀疏矩阵; xtabs(weight ~ from + to, data=foo, sparse=TRUE)

标签: r list matrix sparse-matrix


【解决方案1】:

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

这种“半不鼓励”支持的主要原因是稀疏矩阵在nrow(.) * ncol(.) 很大的意义上特别重要。 在这种情况下,携带(和复制!!)数十万行(和列)名称的成本很高。

在所有这些警告之后,我当然承认您提出了一个非常有效的问题,您现在可能别无选择,并且确实需要使用行和列 names 而不是整数索引。

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

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

从不 是一个好主意。 相反,使用sparseMatrix(...., dimnames = ..) .. 顺便说一下,使用dimnames 参数比之后分别设置colnamesrownames 更有效。

【讨论】:

    【解决方案2】:

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

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

    但是,如果您想要更高效地使用 Matrix,您可能需要编写自己的函数来分配它。比如:

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

    【讨论】:

    • ... 然后在 sparseMatrix() 中使用因子作为 i 和 j?是的,它必须具有计算效率......
    • foo@p 是错误的 - 应该是每列中 bar$weight 的第一个索引(从零开始),然后是 length(bar$weight)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 2023-03-19
    • 1970-01-01
    • 2020-10-16
    • 2014-05-14
    • 2020-01-11
    • 1970-01-01
    相关资源
    最近更新 更多