I am going through The Book of R 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:
By extracting the diagonal elements of the logical matrix created in (c), use any
to confirm there are no TRUE
entries.
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 lower.tri()
and upper.tri()
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 c()
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 diag()
function and assign it to the variable t
.
Next we use each of the lower.tri()
and upper.tri()
functions to identify the lower and upper halves of t
.
In the arguments of both functions, we set diag = FALSE
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 t
.
Since we want to store these as FALSE
, we test to see if they are equal to TRUE
.
Now we can use the c()
function to combine these two halves into one vector s
.
Finally, we can carry out the operation requested in the exercise.
This confirms that extracting the diagonals of an identity matrix will result in there being no logical TRUE
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 any()
, 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.
Edit: 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 which
. Using it saves so much typing!
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 which
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:
Here I used the ==
relational operator to identify and replace the ones in the matrix with zeros. The subsequent steps are as before; convert the zeros to FALSE
then run the matrix through any()
, 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
Top comments (2)
the
diag
function extracts, replaces diagonal of a matrix or creates a diagonal matrix so why don't you just use something like:any(diag(t))
?Thank you for that. I am just starting out learning, so I don't know much about it, thus my journey. I shall definitely explore that.