R 如何有效地在(稀疏)矩阵中插入行?

R 如何有效地在(稀疏)矩阵中插入行?,r,performance,row,sparse-matrix,R,Performance,Row,Sparse Matrix,我有一个巨大的稀疏矩阵,需要在特定的行索引处插入一行。我基本上应用了建议的技术,但这是非常低效的,因为它复制了原始矩阵 简而言之,这里是代码,范围是高效地生成M2(理想情况下,直接替换M,这样就不需要M2): i、 e.在新矩阵的索引2和4处添加行。我要找的是: [1,] 1 1 [2,] . . [3,] 2 2 [4,] 3 3 [5,] . . [6,] 4 4 i、 e.在旧矩阵的索引2和4之前添加了新行。在他的+1回答中@Ben Bolker正确地解释了这一点: 我认为这应该相当有效

我有一个巨大的稀疏矩阵,需要在特定的行索引处插入一行。我基本上应用了建议的技术,但这是非常低效的,因为它复制了原始矩阵

简而言之,这里是代码,范围是高效地生成
M2
(理想情况下,直接替换
M
,这样就不需要
M2
):

i、 e.在新矩阵的索引2和4处添加行。我要找的是:

[1,] 1 1
[2,] . .
[3,] 2 2
[4,] 3 3
[5,] . .
[6,] 4 4

i、 e.在旧矩阵的索引2和4之前添加了新行。在他的+1回答中@Ben Bolker正确地解释了这一点:

我认为这应该相当有效:它以稀疏(
dgCMatrix
dgTMatrix
)格式操纵矩阵的底层行索引和维度


您需要矩阵采用(默认)“dgCMatrix”(压缩稀疏列)格式还是“dgTMatrix”(三元组格式)可以?(如果您不知道,可能是…@CJR,我不确定。我们不能操纵底层数组/索引吗?@Ben Bolker:dgTMatrix也可以开始,因为它可以在之后转换为dgCMatrix。我只为管道运营商添加了tidyverse,承认这有点过分:)我更改了它now@CJR,你认为我的回答如何?在稀疏矩阵中,底层数据结构最好是(非零项的数目)顺序,最坏的顺序是(行数):不是R*C.我的解决方案需要存储顺序(添加行数)*R,在C++中进行(例如通过代码> Rcpp < /代码>)这会更容易一些,因为这样您就可以在没有性能损失的情况下进行迭代。我现在意识到,我编写的解决方案同样适用于
dgTMatrix
dgCMatrix
(事实上,对于压缩行格式来说更难…)谢谢您给出了这个惊人的答案!!我将执行此操作,检查效率,如果没有其他问题,则将此答案标记为最佳答案。:)值得注意的是,它总是在初始矩阵的v中的索引之后添加行。(并不是说这是个问题,如果之前需要,那么
v-1
就可以了。)更新:非常有效,基本上是即时的。作为旁注:
v+0:(长度(v)-1)
是新(结果)矩阵中新插入行(零)的行索引,有助于填充它们(例如,使用插值前后行的平均值)。
[1,] 1 1
[2,] . .
[3,] 2 2
[4,] . .
[5,] 3 3
[6,] 4 4
[1,] 1 1
[2,] . .
[3,] 2 2
[4,] 3 3
[5,] . .
[6,] 4 4
add_rows <- function(M,v) {
    oldind <- seq(dim(M)[1])-1L   ## all rows (0-indexed)
    ## new row indices: count how many rows are inserted before a given row
    ## (maybe a clearer/better/more efficient way to do this?)
    newind <- oldind + as.integer(rowSums(outer(oldind,v,">=")))
    ## modify dimensions
    M@Dim <- M@Dim + c(length(v),0L)
    ## modify row indices (1L accounts for 0 vs 1-indexing)
    M@i <- newind[M@i+1L]
    M
}