5  Matrices

Introduction

A matrix is a series of numbers arranged in rows and columns. We usually abbreviate matrices with a bolded uppercase letter:

\mathbf{A}_{j \times k} = \begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,k} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,k} \\ \vdots & \vdots & \ddots & \vdots \\ a_{j,1} & a_{j,2} & \cdots & a_{j,k} \end{bmatrix}

For example,

\mathbf{A} = \begin{bmatrix} 1&2&3&4\\ 5&6&7&8\\ 9&10&11&12 \end{bmatrix}

To make a matrix in R, there are many possibilities. For the sake of simplicity, I will recommend using the matrix function with the byrow option set to TRUE.

The matrix function takes a vector and converts it to a matrix. By default, the matrix function assumes that the vector is a single column. For example,

matrix(1:4)
     [,1]
[1,]    1
[2,]    2
[3,]    3
[4,]    4

By setting the nrow (number of rows) or ncol (number of columns), the matrix dimensions are set. For example,

matrix(1:4, ncol = 2)
     [,1] [,2]
[1,]    1    3
[2,]    2    4

Note that the default is to fill in the matrix by columns. If you want it to fill by rows, set the byrow option to TRUE.

matrix(1:4, ncol = 2, byrow = TRUE)
     [,1] [,2]
[1,]    1    2
[2,]    3    4

In general, creating matrices by row makes the code and the matrix look similar:

matrix(c(3, 5, 
         2, 3),
       nrow = 2,
       byrow = TRUE)
     [,1] [,2]
[1,]    3    5
[2,]    2    3

To achieve the same matrix without the byrow option set to TRUE is possible, but the code will not be in the same order as the matrix:

matrix(c(3, 2, 
         5, 3),
       nrow = 2)
     [,1] [,2]
[1,]    3    5
[2,]    2    3
NoteYou Try

Make vector A into a 2 by 2 matrix like so:

\mathbf{A}=\begin{bmatrix} 2&3\\ 5&7 \end{bmatrix}

Suggested Solution
# Using the matrix function setting byrow = TRUE
A <- matrix(c(2, 3,
              5, 7),
            nrow = 2,
            byrow = TRUE)

5.1 Appending Matrices

\color{RoyalBlue}{\mathbf{A}}=\begin{bmatrix} \color{RoyalBlue}{1} & \color{RoyalBlue}{2} & \color{RoyalBlue}{3} & \color{RoyalBlue}{4} \\ \color{RoyalBlue}{5} & \color{RoyalBlue}{6} & \color{RoyalBlue}{7} & \color{RoyalBlue}{8} \\ \color{RoyalBlue}{9} & \color{RoyalBlue}{10} & \color{RoyalBlue}{11} & \color{RoyalBlue}{12} \end{bmatrix}, \color{Firebrick}{\mathbf{B}}=\begin{bmatrix} \color{Firebrick}{13} & \color{Firebrick}{14} & \color{Firebrick}{15} & \color{Firebrick}{16} \\ \color{Firebrick}{17} & \color{Firebrick}{18} & \color{Firebrick}{19} & \color{Firebrick}{20} \end{bmatrix}

The equation below means, “Make a new matrix called C by appending B to the bottom of A.”

\mathbf{C}=\begin{bmatrix} \color{RoyalBlue}{\mathbf{A}} \\ \color{FireBrick}{\mathbf{B}} \end{bmatrix}= \begin{bmatrix} \color{RoyalBlue}{1} & \color{RoyalBlue}{2} & \color{RoyalBlue}{3} & \color{RoyalBlue}{4} \\ \color{RoyalBlue}{5} & \color{RoyalBlue}{6} & \color{RoyalBlue}{7} & \color{RoyalBlue}{8} \\ \color{RoyalBlue}{9} & \color{RoyalBlue}{10} & \color{RoyalBlue}{11} & \color{RoyalBlue}{12}\\ \color{Firebrick}{13} & \color{Firebrick}{14} & \color{Firebrick}{15} & \color{Firebrick}{16} \\ \color{Firebrick}{17} & \color{Firebrick}{18} & \color{Firebrick}{19} & \color{Firebrick}{20} \end{bmatrix}

In R, adding new rows to a matrix is done with the rbind function (Think “row bind”). To append rows, matrices must have the same number of columns to be compatible. If the matrices are incompatible, no appending is possible.

A <- matrix(1:12, nrow = 3, byrow = TRUE)
B <- matrix(13:20, nrow = 2, byrow = TRUE)
C <- rbind(A,B)
C
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
[4,]   13   14   15   16
[5,]   17   18   19   20

The cbind function (Think “column bind”) works the same way but it appends columns to the right of a matrix. Matrices must have the same number of rows to be compatible.

A <- matrix(1:4, nrow = 2)
B <- matrix(5:8, nrow = 2)
C <- cbind(A,B)
C
     [,1] [,2] [,3] [,4]
[1,]    1    3    5    7
[2,]    2    4    6    8
NoteYou Try

Make a 2 by 2 matrix A:

A=\begin{bmatrix} 11&13\\ 17&19 \end{bmatrix}

Make a 2 by 2 matrix B:

B=\begin{bmatrix} 11&13\\ 17&19 \end{bmatrix}

Append A and B with rbind to make a 4 by 2 matrix like so:

\begin{bmatrix} 2&3\\ 5&7\\ 11&13\\ 17&19 \end{bmatrix}

Suggested Solution
A <- matrix(c(2, 5, 3, 7), nrow = 2)
B <- matrix(c(11,17,13,19), nrow = 2)
rbind(A, B)
     [,1] [,2]
[1,]    2    3
[2,]    5    7
[3,]   11   13
[4,]   17   19

Now use cbind to make a 2 by 4 matrix:

\begin{bmatrix} 2&3&11&13\\ 5&7&17&19 \end{bmatrix}

Suggested Solution
cbind(A, B)
     [,1] [,2] [,3] [,4]
[1,]    2    3   11   13
[2,]    5    7   17   19

5.2 Selecting parts of a matrix

Often we need to select smaller portions of a larger matrix. For example, suppose we have a 3 by 4 matrix A:

\mathbf{A} = \begin{bmatrix} 1&2&3&4\\ 5&6&7&8\\ 9&10&11&12 \end{bmatrix}

A <- matrix(1:12, nrow = 3, byrow = TRUE)
A
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12

5.2.1 Select a single element of a matrix

To select a single element of a matrix, specify the row and column in brackets after the matrix. For example, the element \mathbf{A}_{3,2} (i.e., the 3rd row and 2nd column of \mathbf{A}) is

A[3,2]
[1] 10
NoteYou Try

Select the element in row 2, column 3

Suggested Solution
A[2,3]
[1] 7

5.2.2 Select a matrix row

Leaving one of the slots in the bracket empty means that you want all of the elements in that row or column.

\mathbf{A}_{1\bullet} is the 1st row of \mathbf{A}.

A[1, ]
[1] 1 2 3 4

5.2.3 Select a matrix column

\mathbf{A}_{\bullet 3} is the 3rd column of \mathbf{A}.

A[, 3]
[1]  3  7 11

By default, whenever a single row, column, or element is returned from a matrix, R drops the row and column dimensions. If you wish to preserve the result in matrix form, set drop to FALSE:

A[, 3, drop = FALSE]
     [,1]
[1,]    3
[2,]    7
[3,]   11

Select column 1 of A.

Suggested Solution
A[, 1]
[1] 1 5 9

5.2.4 Select several columns or rows

A vector of integers will select whichever rows or columns you wish. Here are the 2nd and 3rd rows:

A[2:3, ]
     [,1] [,2] [,3] [,4]
[1,]    5    6    7    8
[2,]    9   10   11   12

Here are the 1st and 4th columns:

A[, c(1, 4)]
     [,1] [,2]
[1,]    1    4
[2,]    5    8
[3,]    9   12

Select columns 1 and 3 of A.

Suggested Solution
A[, c(1, 3)]
     [,1] [,2]
[1,]    1    3
[2,]    5    7
[3,]    9   11

5.2.5 Selecting with Boolean vectors

Here is the first two rows of \mathbf{A}:

A[c(TRUE,TRUE,FALSE),]
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8

This seems like a strange way to do this, but it is actually quite powerful. Any vector of TRUE and FALSE values can be used to select things. For example, select a column only if its first value is greater than 2:

# Create a vector that tests whether the 
# first row elements are greater than 2
s <- A[1, ] > 2 
# Select only the columns whose 
# first value is greater than 2
A[, s] 
     [,1] [,2]
[1,]    3    4
[2,]    7    8
[3,]   11   12

Use a Boolean vector to select columns that begin with 2. The operator for “is equal to” is ==.

Suggested Solution
s <- A[1,] == 2 
# When only one column or row is selected, R returns a vector
A[,s]
[1]  2  6 10
# To force R to return a matrix, set drop = FALSE
A[,s, drop = FALSE]
     [,1]
[1,]    2
[2,]    6
[3,]   10

5.2.6 Selecting with name vectors

Suppose matrix A represents the number of Olympic medals a country has won in different gymnastics events. We can give row and column names to a matrix like so:

rownames(A) <- c("Gold","Silver","Bronze")
colnames(A) <- c("Vault","Uneven Bars","Balance Beam","Floor")
A
       Vault Uneven Bars Balance Beam Floor
Gold       1           2            3     4
Silver     5           6            7     8
Bronze     9          10           11    12

Now we can select rows and columns by names. To select only the gold and bronze meal rows:

A[c("Gold","Bronze"),]
       Vault Uneven Bars Balance Beam Floor
Gold       1           2            3     4
Bronze     9          10           11    12

Use the column names to select the Uneven Bars column

Suggested Solution
A[,"Uneven Bars"]
  Gold Silver Bronze 
     2      6     10 
# or to force R to return a matrix
A[,"Uneven Bars", drop = FALSE]
       Uneven Bars
Gold             2
Silver           6
Bronze          10

Select the intersection of Silver and Floor

Suggested Solution
A["Silver", "Floor"]
[1] 8
# or
A["Silver", "Floor", drop = FALSE]
       Floor
Silver     8

5.3 Replace portions of a matrix

Any portion of a matrix can be replaced with new values. For example, this will replace the first row with zeros:

A[1, ] <- c(0, 0, 0, 0)
A
       Vault Uneven Bars Balance Beam Floor
Gold       0           0            0     0
Silver     5           6            7     8
Bronze     9          10           11    12

This can be done by column or row name as well

A["Gold", ] <- c(0, 0, 0, 0)
A
       Vault Uneven Bars Balance Beam Floor
Gold       0           0            0     0
Silver     5           6            7     8
Bronze     9          10           11    12

Replace the Vault column of \mathbf{A} with a vector of (10,20,30)

Suggested Solution
A[, "Vault"] <- c(10, 20, 30)
A
       Vault Uneven Bars Balance Beam Floor
Gold      10           0            0     0
Silver    20           6            7     8
Bronze    30          10           11    12

5.4 Transposing matrices

To transpose a matrix is to flip its rows into columns.

To transpose a matrix is to write its rows as columns and its columns as rows.

\mathbf{A}' is matrix \mathbf{A} transposed.

If

\mathbf{A}=\begin{bmatrix} 1&2&3\\ 4&5&6 \end{bmatrix}

Then

\mathbf{A}'=\begin{bmatrix} 1&4\\ 2&5\\ 3&6 \end{bmatrix}

5.4.1 Transposing in R

In R the t function transposes matrices.

A <- matrix(1:6, nrow = 2, byrow = TRUE)
A
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
A_prime <- t(A)
A_prime
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
  1. Make a 2 \times 5 matrix A of even numbers up to 20.
  2. Transpose A, assigning it to a variable called A_prime.
  3. Replace the last row (row 5) of A_prime with zeroes.
Suggested Solution
A <- matrix(seq(2, 20, 2), nrow = 2)
A
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    6   10   14   18
[2,]    4    8   12   16   20
A_prime <- t(A)
A_prime
     [,1] [,2]
[1,]    2    4
[2,]    6    8
[3,]   10   12
[4,]   14   16
[5,]   18   20
A_prime[5, ] <- c(0, 0)
A_prime
     [,1] [,2]
[1,]    2    4
[2,]    6    8
[3,]   10   12
[4,]   14   16
[5,]    0    0

5.5 Square matrices

In a square matrix, the number of rows is equal to the number of columns. Some operations in matrix algebra require square matrices. To test whether a matrix is square, test whether the rows and columns of a matrix are equal:

A square matrix has an equal number of rows and columns.
# A is a 3 by 4 matrix, so it is not square
nrow(A) == ncol(A)
[1] FALSE

5.6 Symmetric matrices

A symmetric matrix is a square matrix that is equal to its transpose.

A symmetrix matrix is equal to its transpose. Only square matrices can be symmetric.

\mathbf{A}=\mathbf{A}'

This means that for all elements, a_{ij}=a_{ji}.

Here is an example of a symmetric matrix:

\begin{bmatrix} \color{green}a & \color{Firebrick}b & \color{RoyalBlue}c\\ \color{Firebrick}b & \color{gold}d & \color{DarkOrchid}e\\ \color{RoyalBlue}c & \color{DarkOrchid}e & \color{orange}f \end{bmatrix}

To test whether a matrix is symmetric:

isSymmetric(A)
[1] FALSE

Correlation matrices and covariance matrices are always symmetric.

5.7 Diagonal matrices

A diagonal matrix is a square matrix consisting of zeroes everywhere except the diagonal. For example,

A diagonal matrix has non-zero elements only on the diagonal vector.

\mathbf{A} = \begin{bmatrix} a & 0 & 0\\ 0 & b & 0\\ 0 & 0 & c \end{bmatrix}

5.7.1 Creating diagonal matrices

As will be seen, the diag function does different things depending on the type of input it receives. If its input is a vector, it will create a diagonal matrix. That is, the diag function creates a diagonal matrix \mathbf{A} from a vector \vec{a} like so:

# Make a vector
a <- 1:4
# Make a diagonal matrix
A <- diag(a)
A
     [,1] [,2] [,3] [,4]
[1,]    1    0    0    0
[2,]    0    2    0    0
[3,]    0    0    3    0
[4,]    0    0    0    4

5.7.2 Extracting the diagonal vector from a matrix

The diag function extracts a diagonal vector \vec{a} from a matrix \mathbf{A}.

diag(A)
[1] 1 2 3 4

5.7.3 Replacing the diagonal of a matrix

The diag function can also be used to replace a diagonal of a matrix:

diag(A) <- 5:8
A
     [,1] [,2] [,3] [,4]
[1,]    5    0    0    0
[2,]    0    6    0    0
[3,]    0    0    7    0
[4,]    0    0    0    8