(m1 <- matrix(1:12, 3, 4)) [,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
As with vectors, we can access and assign values within a matrix using the square brackets operator, [], but with one key difference. Matrices require two indices, one to define the row selection and one to define the column selection.
Select the first two rows and the first three columns of m1, then print the selected elements as a matrix.
Select the first and third rows and the second and third columns of m1, then save the selection as a new matrix called m2
Consider the following matrix.
Predict what m1[, 2] will return.
Leaving the row index blank (m1[, 2]) tells R to select all rows. By specifying 2 for the column index, we’re telling R to select the second column. So, we extract all three elements from the second column.
Notice that R returns a plain vector here, not a one-column matrix. By default, R “drops” a dimension when a selection only has one column (or one row). We’ll come back to this idea when we discuss subsetting data frames in the Lists & Data Frames module.
Editing the value of matrix elements works the same way that it did for vectors. We, use the [] operator to select the values we want to overwrite, and then we assign new values for the selected elements using the ordinary assignment operator, <-.
Replace the element in the first row and second column of m3 with 33.
Replace all elements in the range covered by the second and third rows and the first and third columns with 44.
Consider the following matrix.
Predict what the following code will print.
You should notice two changes to the matrix a.
"b".As with vectors, matrices can only store one type of data. When we try to replace the numeric value in a[1, 1] with the length-one character vector "b", R needs to do something to resolve the type discrepancy. Since there’s no unambiguous way to convert "b" to a number, R converts all of a to a character matrix.
Matrices usually obey R’s recycling rules (the same rules you already learned for vectors). If you attempt to perform arithmetic between a matrix and a vector that has fewer elements than the matrix, R will try to make the lengths match by recycling the elements from the vector.
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[,1] [,2] [,3]
[1,] 5 -1 3
[2,] -2 -2 5
[3,] 1 -3 0
[1] 1 2 3
[1] 1 2
As with vectors, R won’t issue a warning if the length of the vector evenly divides the number of elements in the matrix.
[,1] [,2] [,3]
[1,] 2 5 8
[2,] 4 7 10
[3,] 6 9 12
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 4 10 16
[3,] 9 18 27
When the vector’s length is not a multiple of the number of elements in the matrix, recycling triggers a warning.
Warning in m1 + v2: longer object length is not a multiple of shorter object
length
[,1] [,2] [,3]
[1,] 2 6 8
[2,] 4 6 10
[3,] 4 8 10
Warning in m1 * v2: longer object length is not a multiple of shorter object
length
[,1] [,2] [,3]
[1,] 1 8 7
[2,] 4 5 16
[3,] 3 12 9
We can also leverage recycling when generating new matrices. For example, the following code demonstrates a common use-case where we create an empty matrix to fill later. We populated a \(2 \times 2\) matrix by recycling the missing data code, NA, four times.
When populating a matrix with by recycle multi-element vectors, we need to be mindful of the order in which the matrix cells are filled.
2 and 3.We can also use recycling when we want to overwrite multiple matrix elements with the same replacement value.
[,1] [,2] [,3]
[1,] 5 -1 -99
[2,] -2 -2 -99
[3,] 1 -3 0
[,1] [,2] [,3]
[1,] 5 -1 -99
[2,] -2 -2 -99
[3,] 88 99 0
Recycling isn’t a universal shortcut, though. Sometimes, R won’t accommodate our sloppiness. For example, we can’t do any arithmetic with matrices that have different dimensions.
[,1]
[1,] 1
[2,] 3
Error in m1 + m3: non-conformable arrays
Error in m1 * m3: non-conformable arrays
We also can’t do arithmetic between a matrix and vector that contains more elements than the matrix.
Error: dims [product 9] do not match the length of object [18]
Error: dims [product 9] do not match the length of object [18]
When it comes to overwriting matrix elements, R is especially picky about what size of vector it will use to overwrite a selection of matrix elements.
OK
[,1] [,2] [,3]
[1,] 1 1 3
[2,] 2 2 4
[3,] 3 6 9
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 6 9
[,1] [,2] [,3]
[1,] 1 42 42
[2,] 2 42 42
[3,] 3 6 9
Not OK
Error in m1[1:2, 2:3] <- 1:3: number of items to replace is not a multiple of replacement length
# Fails: Replace 4 elements with length-8 vector (8 is bigger than the selection)
m1[1:2, 2:3] <- 1:8Error in m1[1:2, 2:3] <- 1:8: number of items to replace is not a multiple of replacement length
m1[1, ] and m1[, 1]?m1 is a \(3 \times 4\) matrix, v1 is a length-two vector, and v2 is a length-five vector. Why does m1 + v1 recycle silently, while m1 + v2 recycles with a warning? What’s the underlying rule?You’re ready progress if you can:
dim attribute.”matrix(), and predict whether it fills by row or by column.Take the Knowledge Quiz to evaluate your learning.