2

I have written a function to store the diagonal elements of a matrix into a vector. but the output is not as I expected. The code is:

diagonal <- function(x) {
  for (i in nrow(x)) {
    for (j in ncol(x)) {
      if (i == j) {
        a <- x[i, j]
      }
    }
  }
  print(a)
}

I am passing a matrix to the function. What is wrong with the code?

user438383
  • 5,716
  • 8
  • 28
  • 43
Moksh
  • 199
  • 1
  • 1
  • 7
  • 1
    Possible duplicate of [Removing diagonal elements from matrix in R](http://stackoverflow.com/questions/18839090/removing-diagonal-elements-from-matrix-in-r) – 989 Jul 07 '16 at 12:51

1 Answers1

11

We can use the diag function

diag(m1)
#[1] 1 5 9

Or

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

If we are using the for loop, we are looping by the sequence of rows and columns i.e 1:nrow(x)/1:ncol(x) and not by nrow(x)/ncol(x).

diagonal <- function(x) {
  a <- numeric(0)
 for( i in 1:nrow(x)){ 
  for(j in 1:ncol(x)){
     if(i == j) { 
       a <-  c(a, x[i,j])
     } 
    }
  }
 a
 }

diagonal(m1)
#[1] 1 5 9

data

m1 <- matrix(1:9, ncol=3)
akrun
  • 874,273
  • 37
  • 540
  • 662
  • I am aware of the diag() function. I am a beginner at R. so was practicing to write functions – Moksh Jul 07 '16 at 09:30
  • 3
    Better to pre-allocate and fill `a`, rather than terrible performance copy-and-append -- `n = min(nrow(x), ncol(x)); a = numeric(n)`. Rather than iterating over rows / columns that cannot satisfy the condition, why not `for (i in seq_len(n)) a[i] = x[i, i]`? – Martin Morgan Jul 07 '16 at 11:08
  • @MartinMorgan You are right. I was just showing a way to correct the OP's code with minimal interventions. – akrun Jul 07 '16 at 11:09
  • 2
    plus one just for `m1[col(m1)==row(m1)]` – 989 Jul 07 '16 at 12:42