R Matrix包:稀疏矩阵的dgCMatrix类中的属性的含义

Eul*_*ter 2 pointers r matrix sparse-matrix

我看过Matrix包和他们的幻灯片。我试图理解课堂上争论背后的直觉和含义是什么dgCMatrix。我明白那个

\n\n
    \n
  • @i给出矩阵中非零条目的从零开始的行索引.
  • \n
  • @j给出矩阵中非零条目的从零开始的列索引.
  • \n
  • @x给出该位置处的非零元素(i,j)
  • \n
\n\n

但是我不明白指针的含义@p。文档说

\n\n
\n

数字(整数值)指针向量,每一列(或行)一个,指向列(或行)中元素的初始(从零开始)索引。

\n
\n\n

这信息不是很丰富。在同一页面的“详细信息”部分中,他们解释了更多信息

\n\n
\n

如果缺少ior ,则必须是第一个元素为零的非递减整数向量。它提供行或列索引的压缩表示或 \xe2\x80\x9cpointer\xe2\x80\x9d 表示(以缺失者为准)。的扩展形式,其中, 用作(从 1 开始的)行或列索引。jpprep(seq_along(dp),dp)dp <- diff(p)

\n
\n\n

这对我来说绝对是不直观的。有人可以简单解释一下p代表什么吗?我已经创建了一个最小工作示例,但请随意创建一个新示例。

\n\n
\n\n

最小工作示例

\n\n
# Define non-zero values and their row/col indeces\ni_indeces <- c(1, 3, 4, 6, 8, 9)\nj_indeces <- c(2, 9, 6, 3, 9, 10)\nvalues <- c(60, 20, 10, 40, 30, 50)\n# Create the sparse matrix\nA <- sparseMatrix(\n    i=i_indeces,\n    j=j_indeces,\n    x=values,\n    dims=c(10, 20)\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

在哪里

\n\n
> str(A)\nFormal class \'dgCMatrix\' [package "Matrix"] with 6 slots\n  ..@ i       : int [1:6] 0 5 3 2 7 8\n  ..@ p       : int [1:21] 0 0 1 2 2 2 3 3 3 5 ...\n  ..@ Dim     : int [1:2] 10 20\n  ..@ Dimnames:List of 2\n  .. ..$ : NULL\n  .. ..$ : NULL\n  ..@ x       : num [1:6] 60 40 10 20 30 50\n  ..@ factors : list()\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
> A\n10 x 20 sparse Matrix of class "dgCMatrix"\n\n [1,] . 60  . . .  . . .  .  . . . . . . . . . . .\n [2,] .  .  . . .  . . .  .  . . . . . . . . . . .\n [3,] .  .  . . .  . . . 20  . . . . . . . . . . .\n [4,] .  .  . . . 10 . .  .  . . . . . . . . . . .\n [5,] .  .  . . .  . . .  .  . . . . . . . . . . .\n [6,] .  . 40 . .  . . .  .  . . . . . . . . . . .\n [7,] .  .  . . .  . . .  .  . . . . . . . . . . .\n [8,] .  .  . . .  . . . 30  . . . . . . . . . . .\n [9,] .  .  . . .  . . .  . 50 . . . . . . . . . .\n[10,] .  .  . . .  . . .  .  . . . . . . . . . . .\n
Run Code Online (Sandbox Code Playgroud)\n\n

笔记

\n\n

我知道这rep(seq_along(diff(A@p)), diff(A@p))是重新排列的形式j_indeces,但我仍然不明白它的意思。

\n

Eul*_*ter 5

我终于明白了!我将答案发布以供将来参考。查看矩阵A

 [1,] . 60  . . .  . . .  .  . . . . . . . . . . .
 [2,] .  .  . . .  . . .  .  . . . . . . . . . . .
 [3,] .  .  . . .  . . . 20  . . . . . . . . . . .
 [4,] .  .  . . . 10 . .  .  . . . . . . . . . . .
 [5,] .  .  . . .  . . .  .  . . . . . . . . . . .
 [6,] .  . 40 . .  . . .  .  . . . . . . . . . . .
 [7,] .  .  . . .  . . .  .  . . . . . . . . . . .
 [8,] .  .  . . .  . . . 30  . . . . . . . . . . .
 [9,] .  .  . . .  . . .  . 50 . . . . . . . . . .
[10,] .  .  . . .  . . .  .  . . . . . . . . . . .
Run Code Online (Sandbox Code Playgroud)

属性p

> A@p
 [1] 0 0 1 2 2 2 3 3 3 5 6 6 6 6 6 6 6 6 6 6 6
Run Code Online (Sandbox Code Playgroud)

基本上计算每行中非零元素的数量。它是这样构造的

  • 第一个元素总是0按照惯例(不知道为什么),所以p = [0]
  • 接下来,从矩阵的左上角(即[1, 1])开始,我们从最左边的列到最右边的列查看每一列,然后将0以下数量添加到“计数器”(现在设置为 )中:该列中的非零元素。

    • 1没有非零元素,因此我们将其添加0到计数器中。p=[0,0]
    • 2有一个非零元素 ( 60),因此我们将其添加1到计数器中p=[0, 0, 0+1]=[0,0,1]
    • 3有一个非零元素 ( 40),因此p=[0, 0, 1, 1+1]=[0, 0, 1, 2]
    • 4没有非零元素,因此 p=[0, 0, 1, 2, 2+0]=[0, 0, 1, 2, 2]
    • 5没有非零元素,因此p=[0, 0, 1, 2, 2, 2]
    • 6有一个非零元素 ( 10),因此p=[0, 0, 1, 2, 2, 2, 3]
    • 7没有非零元素,因此p=[0, 0, 1, 2, 2, 2, 3, 3]
    • 8没有非零元素,因此p=[0, 0, 1, 2, 2, 2, 3, 3, 3]
    • 9有两个非零元素 (2030) 所以p=[0, 0, 1, 2, 2, 2, 3, 3, 3, 5]
    • 10有 1 个非零元素 ( 50),因此p=[0, 0, 1, 2, 2, 2, 3, 3, 3, 5, 6]
    • 列的元素全部11为零20,因此我们追加[6, 6, 6, 6, 6, 6, 6, 6, 6, 6]

这样我们就得到了我们想要的p。背后的直觉是,它是从左到右按列有多少个非零元素的计数器。