【问题标题】:Extracting off-diagonal slice of large matrix提取大矩阵的非对角切片
【发布时间】:2012-07-30 08:44:33
【问题描述】:

我有一个很大的 nxn 矩阵,想取出不同大小的非对角线切片。例如:

1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6

我想要一个 R 函数,当给定矩阵和“对角线切片的宽度”时,它将返回仅包含这些值的 nxn 矩阵。所以对于上面的矩阵,比如 3,我会得到:

1 x x x x x
1 2 x x x x
1 2 3 x x x
x 2 3 4 x x
x x 3 4 5 x
x x x 4 5 6

目前我正在使用(原谅我)一个非常慢的 for 循环:

getDiags<-function(ndiags, cormat){
  resmat=matrix(ncol=ncol(cormat),nrow=nrow(cormat))
  dimnames(resmat)<-dimnames(cormat)
  for(j in 1:ndiags){
    resmat[row(resmat) == col(resmat) + j] <- 
      cormat[row(cormat) == col(cormat) + j]
  }
  return(resmat)
}

我意识到这是解决这个问题的一种非常“非 R”的方式。有没有更好的方法,可能使用 diag 或 lower.tri?

【问题讨论】:

    标签: r matrix slice diagonal


    【解决方案1】:
    size <- 6
    mat <- matrix(seq_len(size ^ 2), ncol = size)
    
    
    low <- 0
    high <- 3
    
    delta <- rep(seq_len(ncol(mat)), nrow(mat)) - 
        rep(seq_len(nrow(mat)), each = ncol(mat))
    #or Ben Bolker's better alternative
    delta <- row(mat) - col(mat)
    mat[delta < low | delta > high] <- NA
    mat
    

    这适用于我机器上的 5000 x 5000 矩阵

    【讨论】:

    • 此方法用于我的矩阵中的 10 次诊断:2.125 我的旧方法(已过期):15.170 - 太好了,谢谢!
    • 你也可以使用delta &lt;- row(mat)-col(mat);它可能运行起来有点慢,但很容易阅读......
    • @BenBolker +1 为您的解决方案。它实际上快了大约 30%,并且可以处理更大的矩阵(在我的机器上是 8000 对 6000)
    【解决方案2】:

    如果您想使用upper.trilower.tri,您可以编写如下函数:

    cormat <- mapply(rep, 1:6, 6)
    
    u.diags <- function(X, n) {
      X[n:nrow(X),][lower.tri(X[n:nrow(X),])] <- NA
      return(X)
    }
    

    l.diags <- function(X, n) {
      X[,n:ncol(X)][upper.tri(X[,n:ncol(X)])] <- NA
      return(X)
    }
    

    n.diags <- function(X, n.u, n.l) {
      X[n.u:nrow(X),][lower.tri(X[n.u:nrow(X),])] <- NA
      X[,n.l:ncol(X)][upper.tri(X[,n.l:ncol(X)])] <- NA
      return(X)
    }
    

    l.diags(cormat, 3)
    u.diags(cormat, 3)
    n.diags(cormat, 3, 1)
    

    【讨论】:

      【解决方案3】:

      你可以这样做:

      矩阵:

      m<-
      matrix(1:6,ncol = 6, nrow=6 ,byrow = T)
      

      功能:

      n_diag <- function (x, n) {
          d <- dim(x)
          ndiag <- .row(d) - n >= .col(d)
          x[upper.tri(x) | ndiag] <- NA
          return(x)
      }
      

      致电:

      n_diag(m,3)
      
      #     [,1] [,2] [,3] [,4] [,5] [,6]
      #[1,]    1   NA   NA   NA   NA   NA
      #[2,]    1    2   NA   NA   NA   NA
      #[3,]    1    2    3   NA   NA   NA
      #[4,]   NA    2    3    4   NA   NA
      #[5,]   NA   NA    3    4    5   NA
      #[6,]   NA   NA   NA    4    5    6
      

      只是为了好玩:

      #lapply(1:6, n_diag, x = m)
      

      【讨论】:

        猜你喜欢
        • 2020-02-05
        • 1970-01-01
        • 2021-09-30
        • 1970-01-01
        • 1970-01-01
        • 2013-08-09
        • 1970-01-01
        • 1970-01-01
        • 2021-06-17
        相关资源
        最近更新 更多