R中的diag()函数

时间:2013-12-10 08:39:28

标签: r

有没有办法在不使用内置函数或迭代的情况下在Matrix中使用diag()函数?

   M<-matrix(1:9, ncol=3) # make a matrix 

    q5b<-function(M){ #function

    }

我知道M[1,1]M[2,2]M[3,3]会给我与diag(M)相同的输出。但是,如果没有for循环,我无法想到一种方法。

我的思维过程是我应该有一个条件,矩阵中的row index == column index然后打印该值。我很感激任何建议。

2 个答案:

答案 0 :(得分:8)

只是基于另一个矩阵的子集:

> diag(M)
[1] 1 5 9
> M[matrix(rep(sequence(ncol(M)), 2), ncol = 2)]
[1] 1 5 9

上述问题会在非方阵中遇到问题,因此我们将其修改如下。

作为你的功能,问题5b的一个答案可能是:

q5b <- function(M) { 
  A <- sequence(ncol(M))[sequence(min(nrow(M), ncol(M)))]
  M[cbind(A, A)]
}

更新:基准测试总是很有趣

library(microbenchmark)

fun1 <- function(M) diag(M)
fun2 <- function(M) M[row(M) == col(M)]
fun3 <- function(M) {
  A <- sequence(ncol(M))[sequence(min(nrow(M), ncol(M)))]
  M[cbind(A, A)]
}    

set.seed(1)
M <- matrix(rnorm(1000*1000), ncol = 1000)

microbenchmark(fun1(M), fun2(M), fun3(M), times = 100)
# Unit: microseconds
#     expr       min        lq     median        uq        max neval
#  fun1(M)  4654.825  4747.408  4822.8865  4912.690   5877.866   100
#  fun2(M) 53270.266 54813.606 55059.0695 55749.062 200384.531   100
#  fun3(M)    66.284    82.321   118.8835   129.361    191.155   100

答案 1 :(得分:8)

您可以使用函数rowcol来查找列号与行号相同的索引:

row(M) == col(M)
#       [,1]  [,2]  [,3]
# [1,]  TRUE FALSE FALSE
# [2,] FALSE  TRUE FALSE
# [3,] FALSE FALSE  TRUE

M[row(M) == col(M)]
# [1] 1 5 9