首页 文章

用索引矩阵有效地更新矩阵元素

提问于
浏览
3

我有一个索引矩阵,其中一些索引重复 . 我在下面举一个例子 .

我有另一个矩阵A,其尺寸与索引兼容,并在任何地方都启动为0 . 我想做点什么

A[I] += 1

我面临两个问题:

  • A[I] = A[I] + 1 效率太低

  • 矩阵 I 有冗余索引 . 例如,第2行和第6行是相同的,我想获得 A[1,2] = 2

部分答案是创建一个3列矩阵,其中两个第一列是 unique(I) 的乘积,第三列是计数,但我也没有看到任何解决方案 . 任何指针或帮助将不胜感激!

> I is:
     [,1] [,2]
[1,]    1    1
[2,]    1    2
[3,]    1    3
[4,]    1    4
[5,]    1    1
[6,]    1    2
[7,]    1    3

2 回答

  • 3

    使用稀疏矩阵方法可能是最快的(参见Matrix包和其他方法) .

    使用标准matricies,您可以使用 xtabs 函数然后矩阵分配(根据注释编辑)折叠相同的行:

    I <- cbind(1, c(1:4,1:3))
    
    tmp <- as.data.frame(xtabs( ~I[,1]+I[,2] ))
    
    A <- matrix(0, nrow=5, ncol=5)
    tmp2 <- as.matrix(tmp[,1:2])
    tmp3 <- as.numeric(tmp2)
    dim(tmp3) <- dim(tmp2)
    A[ tmp3 ] <- tmp[,3]
    A
    

    你可以通过将核心功能从 as.data.frame.table 中拉出来而不是转换为数据帧然后再返回来使它更快一些 .

    这是另一个可能更有效的版本 . 它将覆盖由 xtabs 计算的一些0 's with other 0':

    I <- cbind(1:5,1:5)
    A <- matrix(0, 5, 5)
    
    tmp <- xtabs( ~I[,2]+I[,1] )
    
    A[ as.numeric(rownames(tmp)), as.numeric(colnames(tmp)) ] <- c(tmp)
    A
    

    如果A矩阵具有dimnames并且I矩阵具有名称而不是索引,那么后面的这个也将起作用(只需删除 as.numeric .

  • 2

    干得好:

    ## Reproducible versions of your A and I objects
    A <- matrix(0, nrow=2, ncol=5)
    ## For computations that follow, you'll be better off having this as a data.frame
    ## (Just use `I <- as.data.frame(I)` to convert a matrix object I).
    I <- read.table(text=" 1    1
    1    2
    1    3
    1    4
    1    1
    1    2
    1    3", header=FALSE)
    
    ## Create data.frame with number of times each matrix element should
    ## be incremented
    I$count <- ave(I[,1], I[,1], I[,2], FUN=length)
    I <- unique(I)
    
    ## Replace desired elements, using a two column matrix (the "third form of
    ## indexing" mentioned in "Matrices and arrays" section" of ?"[").
    A[as.matrix(I[1:2])] <- I[[3]]
    
    A
    #      [,1] [,2] [,3] [,4] [,5]
    # [1,]    2    2    2    1    0
    # [2,]    0    0    0    0    0
    

相关问题