Excluding Diagonal Elements from a Matrix in R
Tags: r, beginners, learning
Published: 2019-01-10 18:12:15

---
title: Excluding Diagonal Elements from a Matrix in R
published: true
description: 
tags: #R #Beginner #Learning
---

<img src="https://egmgem.com/blog/wp-content/uploads/2019/01/00-rmatrix-1024x433.jpg" alt="The Book of R and a 10x10 Identity Matrix">

I am going through <em>The Book of R</em> by Tilman M. Davies as an introduction into things Data Science. During one of the exercises (4.1 part e on page 64), I came across this problem:

<em>By extracting the diagonal elements of the logical matrix created in (c), use  <code>any</code> to confirm there are no <code>TRUE</code> entries.</em>

The said matrix is a 10×10 identity matrix. How does one do that extraction and testing? I tried everything that had been taught from the book thus far and could not find a way to do it. Off to Google I went in search of a solution.

From various sources, I got to learn of the <code>lower.tri()</code> and <code>upper.tri()</code> functions. Those seemed like they could do what I wanted. Only hitch is, I can only extract either the lower or upper half depending on the function used.

However, I have learned that you can use the <code>c()</code> function to combine different items into one vector. That means I can use the two functions to extract the portions I need, then combine the results, then do the required test.

For simplicity, I shall use a 3×3 identity matrix to demonstrate. First, let us form it using the <code>diag()</code> function and assign it to the variable <code>t</code>.

<img src="http://egmgem.com/blog/wp-content/uploads/2019/01/01-diag.jpg" alt="Command to create the 3x3 identity matrix">

Next we use each of the <code>lower.tri()</code> and <code>upper.tri()</code> functions to identify the lower and upper halves of <code>t</code>.

<img src="http://egmgem.com/blog/wp-content/uploads/2019/01/02-loup.jpg" alt="Isolating the lower and upper halves.">

In the arguments of both functions, we set <code>diag = FALSE</code> since we want to make sure the diagonals are left out. If we did not have that argument set, we would capture the ones in the diagonal, contrary to our goal.

Now we can extract each of those halves of zeros from <code>t</code>.

<img src="http://egmgem.com/blog/wp-content/uploads/2019/01/03-extract.jpg" alt="Extracting the zeros from the matrix.">

Since we want to store these as <code>FALSE</code>, we test to see if they are equal to <code>TRUE</code>.

<img src="http://egmgem.com/blog/wp-content/uploads/2019/01/04-test.jpg" alt="Testing if equal to TRUE to get FALSE vallues.">

Now we can use the <code>c()</code> function to combine these two halves into one vector <code>s</code>.

<img src="http://egmgem.com/blog/wp-content/uploads/2019/01/05-combine.jpg" alt="Combining the values into one vector.">

Finally, we can carry out the operation requested in the exercise.

<img src="http://egmgem.com/blog/wp-content/uploads/2019/01/06-any.jpg" alt="Using any() to test for presence of TRUE values.">

This confirms that extracting the diagonals of an identity matrix will result in there being no logical <code>TRUE</code> values left in the matrix.

There is probably a simpler way to do this. I also have a niggling thought that there is a way to extract the diagonal ones and leave the zeros in the matrix, then test the matrix using <code>any()</code>, but I have yet to find out how. This is one of those beginner solutions that a certain period from now will be proof of how much my knowledge of things R will have grown. If you are aware of how to do this in a simpler, more straight forward way, please do share in the comments.

<strong>Edit:</strong> And yes, there is a simpler way! I just needed to be patient and read on a few more pages of the book to page 69 which introduces the function <code>which</code>. Using it saves so much typing!

<img src="http://egmgem.com/blog/wp-content/uploads/2019/01/07-which.jpg" alt="Much typing saved by using which()">

Basically, the command selects elements in the vector that are to be extracted based on a test given. To extract some and leave others, you append a hyphen to <code>which</code> resulting in anything that passes the test being deleted.

My original question still remains though. Is there a way to extract the unwanted elements and still remain with a matrix? A possible solution would probably be to replace the ones with zeros then just test the matrix as a whole. Again, a little patience and reading on and paying attention (as this solution came after reading page 68) is all I needed. That led me the following:

<img src="http://egmgem.com/blog/wp-content/uploads/2019/01/08-simplest.jpg" alt="Using the == relational operator on the matrix.">

Here I used the <code>==</code> relational operator to identify and replace the ones in the matrix with zeros. The subsequent steps are as before; convert the zeros to <code>FALSE</code> then run the matrix through <code>any()</code>, giving us the answer expected.

This is all very exciting. There is lots to learn and discover about programming with R, and data science by extension!

Resources:

The Book of R: https://nostarch.com/bookofr