You're all familiar with what a matrix is mathematically. It is a 2-dimensional array of symbols -- like a 2-dimensional vector. In fact, that's how R implements matrices; they are vectors organized into an array with a multidimensional index.
Matrices are instantiated with the matrix
function, in which we specify the vector of entries and the numbers of rows and columns.
v1 <- 1:9 # a vector of length 9 = 3 x 3
m1 <- matrix(v1, nrow = 3, ncol = 3)
m1
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
You see it filled in the entries going down the column. If you try to form a matrix with a vector that's too short, R pads it with NA's.
Matrices of characters or logicals can also be created.
m2 <- matrix(letters[1:8], nrow = 2, ncol = 4)
m2
## [,1] [,2] [,3] [,4]
## [1,] "a" "c" "e" "g"
## [2,] "b" "d" "f" "h"
But if you try to mix numeric and character entries, the numbers are converted to characters, just like with vectors.
R has functions that return dimnesions just like length
works for vectors.
nrow(m2)
## [1] 2
ncol(m2)
## [1] 4
dim(m2)
## [1] 2 4
Just like a vector can have names associated to the entries, a matrix can have names for columns and rows.
dim(m1)
## [1] 3 3
colnames(m1) <- c("C1", "C2", "C3")
rownames(m1) <- c("R1", "R2", "R3")
m1
## C1 C2 C3
## R1 1 4 7
## R2 2 5 8
## R3 3 6 9
There are no surprises in how a cell in a matrix is identified.
m2
## [,1] [,2] [,3] [,4]
## [1,] "a" "c" "e" "g"
## [2,] "b" "d" "f" "h"
m2[1, 2] # row 1, column 2
## [1] "c"
You can also use row and column names to pin down an entry.
m1["R2", "C3"]
## [1] 8
Specifying ranges of columns and rows will give a submatrix.
m1[1:2, 2:3] # The row and column names ride along
## C2 C3
## R1 4 7
## R2 5 8
Leaving one slot empty fetches all rows or columns.
m2[, 1:3]
## [,1] [,2] [,3]
## [1,] "a" "c" "e"
## [2,] "b" "d" "f"
Note that if you specify a single row or column, R drops the matrix structure and returns a vector.
v2 <- m1[1, ]
v2
## C1 C2 C3
## 1 4 7
class(v2)
## [1] "integer"
Equalities and inequalities of matrices return logical matrices of the same dimensions.
m1 > 4
## C1 C2 C3
## R1 FALSE FALSE TRUE
## R2 FALSE TRUE TRUE
## R3 FALSE TRUE TRUE
Subsetting with a logical vector in the row or column slot selects the TRUE rows or columns. You can also subset with logical matrices, although it isnt used much.
m1[m1 > 4]
## [1] 5 6 7 8 9
Here, we just got the vector. This may not be very useful but it may be for assignment.
m1[m1 > 4] <- 0
m1
## C1 C2 C3
## R1 1 4 0
## R2 2 0 0
## R3 3 0 0
Arithmetic operations with matrices are computed component-wise, just like vectors. This can lead to surprising behavior.
m1
## C1 C2 C3
## R1 1 4 0
## R2 2 0 0
## R3 3 0 0
2 * m1
## C1 C2 C3
## R1 2 8 0
## R2 4 0 0
## R3 6 0 0
w <- c(-1, -2, -3)
m1 * w
## C1 C2 C3
## R1 -1 -4 0
## R2 -4 0 0
## R3 -9 0 0
This multipled each column by w, entry by entry.
To perform matrix multiplication, use the %*% operator.
m1 %*% w
## [,1]
## R1 -9
## R2 -2
## R3 -3
You may need to transpose a matrix or extract the diagonal. The R functions for those are t
and diag
. R also has functions for doing linear algebra, like singular value decomposition.