Eric Zivot
Wednesday, March 18, 2015
You create matrices using the matrix()
constructor function:
args(matrix)
## function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
## NULL
# fill matrix by column (default)
matA = matrix(data=c(1,2,3,4,5,6), nrow=2, ncol=3)
matA
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
class(matA)
## [1] "matrix"
# fill matrix by row
matA = matrix(data=c(1,2,3,4,5,6), nrow=2, ncol=3, byrow=TRUE)
matA
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
You can name the rows and columns of a matrix using the functions dimnames()
, rownames()
and colnames()
:
dim(matA)
## [1] 2 3
dimnames(matA)
## NULL
dimnames(matA) = list(c("row1","row2"),c("col1","col2","col3"))
matA
## col1 col2 col3
## row1 1 2 3
## row2 4 5 6
colnames(matA) = c("Col1", "Col2", "Col3")
rownames(matA) = c("Row1", "Row2")
matA
## Col1 Col2 Col3
## Row1 1 2 3
## Row2 4 5 6
You can subset the elements of a matrix by position or name:
# subset by position
matA[1, 2]
## [1] 2
# subset by name
matA["Row1", "Col1"]
## [1] 1
You can extract entire rows or columns
# extract first row
matA[1, ]
## Col1 Col2 Col3
## 1 2 3
# extract 2nd column
matA[, 2]
## Row1 Row2
## 2 5
When you extract an entire row or column of a matrix, R drops the dimension attributes of the result. That is, what you get is a numeric vector and not a row or column matrix. To preserve the dimension attributes the optional argument drop=FALSE
:
# preserve dimension attributes using drop=FALSE
matA[1, , drop=FALSE]
## Col1 Col2 Col3
## Row1 1 2 3
matA[, 2, drop=FALSE]
## Col2
## Row1 2
## Row2 5
Vectors in R do not have dimension attributes. They appear as row vectors but that is just how they are printed on screen.
xvec = c(1,2,3)
xvec
## [1] 1 2 3
class(xvec)
## [1] "numeric"
dim(xvec)
## NULL
names(xvec) = c("x1", "x2", "x3")
xvec
## x1 x2 x3
## 1 2 3
# coerce vector to class matrix: note column vector is created
xvec = as.matrix(xvec)
xvec
## [,1]
## x1 1
## x2 2
## x3 3
class(xvec)
## [1] "matrix"
# create row vector
xvec = c(1,2,3)
xvec = matrix(xvec, nrow=1)
xvec
## [,1] [,2] [,3]
## [1,] 1 2 3
Note: R has many as.
functions for coercing the class of an object to another class.
Transposing a matrix interchanges rows and columns:
matA = matrix(data=c(1,2,3,4,5,6), nrow=2, ncol=3,
byrow=TRUE)
t(matA)
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
xvec = c(1,2,3)
t(xvec)
## [,1] [,2] [,3]
## [1,] 1 2 3
A symmetric matrix is equal to its transpose:
matS = matrix(c(1,2,2,1),2,2)
matS
## [,1] [,2]
## [1,] 1 2
## [2,] 2 1
# check for symmetry
matS == t(matS)
## [,1] [,2]
## [1,] TRUE TRUE
## [2,] TRUE TRUE
Element by element operations require that all matrices have the same dimension and apply to each element the matrices.
matA = matrix(c(4,9,2,1),2,2, byrow=TRUE)
matB = matrix(c(2,0,0,7),2,2, byrow=TRUE)
matA
## [,1] [,2]
## [1,] 4 9
## [2,] 2 1
matB
## [,1] [,2]
## [1,] 2 0
## [2,] 0 7
Matrix addition and subtraction are element by element operations:
# matrix addition
matC = matA + matB
matC
## [,1] [,2]
## [1,] 6 9
## [2,] 2 8
# matrix subtraction
matC = matA - matB
matC
## [,1] [,2]
## [1,] 2 9
## [2,] 2 -6
Multipling a matrix by a scalar (single number) is an element by element operation:
matA = matrix(c(3,-1,0,5), 2, 2,
byrow=TRUE)
matA
## [,1] [,2]
## [1,] 3 -1
## [2,] 0 5
matC = 2*matA
matC
## [,1] [,2]
## [1,] 6 -2
## [2,] 0 10
Matrix multiplication only works on conformable matrices:
matA = matrix(1:4,2,2, byrow=TRUE)
matB = matrix(c(1,2,1,3,4,2),2,3, byrow=TRUE)
matA
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
matB
## [,1] [,2] [,3]
## [1,] 1 2 1
## [2,] 3 4 2
dim(matA)
## [1] 2 2
dim(matB)
## [1] 2 3
matC = matA%*%matB
matC
## [,1] [,2] [,3]
## [1,] 7 10 5
## [2,] 15 22 11
The \((i,j)\) element of matC
is the dot product of the i’th row of matA
with the j’th column of matB
Multiplying two non-conformable matrices results in an error:
# here B%*%A doesn't work b/c A and B are not comformable
# matB%*%matA
# Error in matB %*% matA : non-conformable arguments
Create identity matrix of dimension 2:
matI = diag(2)
matI
## [,1] [,2]
## [1,] 1 0
## [2,] 0 1
Multiplying a matrix by the identity matrix returns the original matrix.
matA = matrix(c(1,2,3,4), 2, 2, byrow=TRUE)
matI%*%matA
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
matA%*%matI
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
Create a diagonal matrix with \(c=(1,2,3)\) along the main diagonal.
matD = diag(1:3)
matD
## [,1] [,2] [,3]
## [1,] 1 0 0
## [2,] 0 2 0
## [3,] 0 0 3
In R, the function solve()
computes the inverse of a matrix.
matA
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
matA.inv = solve(matA)
matA.inv
## [,1] [,2]
## [1,] -2.0 1.0
## [2,] 1.5 -0.5
matA%*%matA.inv
## [,1] [,2]
## [1,] 1 1.11e-16
## [2,] 0 1.00e+00
matA.inv%*%matA
## [,1] [,2]
## [1,] 1 4.44e-16
## [2,] 0 1.00e+00
The solution of two linear equations in two unknows is at the intersection of the two lines:
curve(1-x, 0, 1, lwd=2, ylab="y")
abline(a=-1, b=2, lwd=2)
title("x+y=1, 2x-y=1")
The system of linear equations can be expressed in matrix form as \(Az = b\). The solution is \(z = A^{-1}b\):
matA = matrix(c(1,1,2,-1), 2, 2, byrow=TRUE)
vecB = c(1,1)
matA.inv = solve(matA)
z = matA.inv%*%vecB
z
## [,1]
## [1,] 0.667
## [2,] 0.333
\[ \sum_{k=1}^{n}x_{k} = \mathbf{x}^{\prime}\mathbf{1} \]
onevec = rep(1,3)
xvec = c(1,2,3)
# sum elements in x - returns 1 x 1 matrix
t(xvec)%*%onevec
## [,1]
## [1,] 6
# more efficient
crossprod(xvec, onevec)
## [,1]
## [1,] 6
# more efficient still - returns a number
sum(xvec)
## [1] 6
\[ \sum_{k=1}^{n}x_{k}^{2} = \mathbf{x}^{\prime}\mathbf{x} \]
xvec
## [1] 1 2 3
t(xvec)%*%xvec
## [,1]
## [1,] 14
# more efficient
crossprod(xvec)
## [,1]
## [1,] 14
# most efficient
sum(xvec^2)
## [1] 14
\[ \sum_{k=1}^{n}x_{k}y_{k} = \mathbf{x}^{\prime}\mathbf{y} \]
yvec = 4:6
xvec
## [1] 1 2 3
yvec
## [1] 4 5 6
t(xvec)%*%yvec
## [,1]
## [1,] 32
crossprod(yvec, xvec)
## [,1]
## [1,] 32
sum(xvec*yvec)
## [1] 32