dgCMatrix用来存储矩阵的一种数据格式,这种数据格式很适合存储稀疏矩阵(即矩阵中大部分值为0)。dgCMatrix使用三个数组(分别是i,p,x)来存储矩阵。怎么存的呢?
先举一个普通矩阵的例子:
3 0 0
0 4 0
8 0 5
0 6 0
如果要把它转换成dgCMatrix格式,搞清楚对应的i,p,x值就行了。
x是存储矩阵中所有的非零值按从上到下,从左往右的顺序的排列。对于上面这个例子:
x = 3, 8, 4, 6, 5
i则存储了这些非零值对应的行索引,并且顺序与x一一对应。值得注意的是,行号是从0开始的,所以3在第0行,8在第2行,因此i数组应该是:
i = 0, 2, 1, 3, 2
p这个数组稍微复杂,它是存储了当前列前面所有非零值的总数。
第一列前面没有,所以p[1]是0。
第二列前面共有2个,分别是3和8,所以p[2]是2;
第三列前面共有4个,即3,8,4,6,所以p[3]是4;
此外,虽然没有第四列,但p在最后仍然会有一个p[4],也就是虚拟的“第四列”前面的所有非零值总数,当然也就是整个矩阵中所有非零值的数量,即p[4]=5。综上,p的值为:
p = 0, 2, 4, 5
视野拓展
你可能会发现,按照这种方式,p的第一个值永远都是0。并且,“当前列前面所有的非零值”这种表述实在是违反直觉。这其实是因为dgCMatrix这种存储方式,最早并不是在R语言中使用的。而在其他很多编程语言中,数组下标都是从0开始,这样的话,p的第一个值为0,就可以让数组下标刚好与矩阵列的下标对应,从而便于理解p了:例如p[4]就代表前4列所有非零值的数量。然而R语言的数组下标是从1开始的,这样的话,p的第一个值被0占据后,所有的数组下标就与实际的矩阵列号错开了。这样的话,R在最开始创建dgCMatrix的时候应该考虑将p的第一位0去掉,从而让R中的p下标数与矩阵列号对应。