3
MATR ICES AND AR R AYS
A matrix is a vector with two additional
attributes: the number of rows and the
number of columns. Since matrices are vec-
tors, they also have modes, such as numeric and
character. (On the other hand, vectors are not one-
column or one-row matrices.)
Matrices are special cases of a more general R type of object: arrays.
Arrays can be multidimensional. For example, a three-dimensional array
would consist of rows, columns, and layers, not just rows and columns as
in the matrix case. Most of this chapter will concern matrices, but we will
briefly discuss higher-dimensional arrays in the final section.
Much of R’s power comes from the various operations you can perform
on matrices. We’ll cover these operations in this chapter, especially those
analogous to vector subsetting and vectorization.
3.1 Creating Matrices
Matrix row and column subscripts begin with 1. For example, the upper-left
corner of the matrix a is denoted a[1,1]. The internal storage of a matrix is
in column-major order, meaning that first all of column 1 is stored, then all of
column 2, and so on, as you saw in Section 2.1.3.
One way to create a matrix is by using the matrix() function:
> y <- matrix(c(1,2,3,4),nrow=2,ncol=2)
> y
[,1] [,2]
[1,] 1 3
[2,] 2 4
Here, we concatenate what we intend as the first column, the numbers
1 and 2, with what we intend as the second column, 3 and 4. So, our data is
(1,2,3,4). Next, we specify the number of rows and columns. The fact that R
uses column-major order then determines where these four numbers are put
within the matrix.
Since we specified the matrix entries in the preceding example, and
there were four of them, we did not need to specify both ncol and nrow; just
nrow or ncol would have been enough. Having four elements in all, in two
rows, implies two columns:
> y <- matrix(c(1,2,3,4),nrow=2)
> y
[,1] [,2]
[1,] 1 3
[2,] 2 4
Note that when we then print out y, R shows us its notation for rows and
columns. For instance, [,2] means the entirety of column 2, as can be seen
in this check:
> y[,2]
[1] 3 4
Another way to build y is to specify elements individually:
> y <- matrix(nrow=2,ncol=2)
> y[1,1] <- 1
> y[2,1] <- 2
> y[1,2] <- 3
> y[2,2] <- 4
> y
[,1] [,2]
[1,] 1 3
[2,] 2 4
Note that we do need to warn R ahead of time that y will be a matrix and
give the number of rows and columns.
60 Chapter 3
Though internal storage of a matrix is in column-major order, you can
set the byrow argument in matrix() to true to indicate that the data is coming
in row-major order. Here’s an example of using byrow:
> m <- matrix(c(1,2,3,4,5,6),nrow=2,byrow=T)
> m
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
Note that the matrix is still stored in column-major order. The byrow
argument enabled only our input to come in row-major form. This may be
more convenient if you are reading from a data file organized that way, for
example.
3.2 General Matrix Operations
Now that we’ve covered the basics of creating a matrix, we’ll look at some
common operations performed with matrices. These include performing
linear algebra operations, matrix indexing, and matrix filtering.
3.2.1 Performing Linear Algebra Operations on Matrices
You can perform various linear algebra operations on matrices, such as
matrix multiplication, matrix scalar multiplication, and matrix addition.
Using y from the preceding example, here is how to perform those three
operations:
> y %*% y # mathematical matrix multiplication
[,1] [,2]
[1,] 7 15
[2,]10 22
> 3*y # mathematical multiplication of matrix by scalar
[,1] [,2]
[1,] 3 9
[2,] 6 12
> y+y # mathematical matrix addition
[,1] [,2]
[1,] 2 6
[2,] 4 8
For more on linear algebra operations on matrices, see Section 8.4.
Matrices and Arrays 61
3.2.2 Matrix Indexing
The same operations we discussed for vectors in Section 2.4.2 apply to matri-
ces as well. Here’s an example:
> z
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 1 0
[3,] 3 0 1
[4,] 4 0 0
> z[,2:3]
[,1] [,2]
[1,] 1 1
[2,] 1 0
[3,] 0 1
[4,] 0 0
Here, we requested the submatrix of z consisting of all elements with col-
umn numbers 2 and 3 and any row number. This extracts the second and
third columns.
Here’s an example of extracting rows instead of columns:
> y
[,1] [,2]
[1,]11 12
[2,]21 22
[3,]31 32
> y[2:3,]
[,1] [,2]
[1,]21 22
[2,]31 32
> y[2:3,2]
[1] 22 32
You can also assign values to submatrices:
> y
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> y[c(1,3),] <- matrix(c(1,1,8,12),nrow=2)
> y
[,1] [,2]
[1,] 1 8
[2,] 2 5
[3,] 1 12
62 Chapter 3
Here, we assigned new values to the first and third rows of y.
And here’s another example of assignment to submatrices:
> x <- matrix(nrow=3,ncol=3)
> y <- matrix(c(4,5,2,3),nrow=2)
> y
[,1] [,2]
[1,] 4 2
[2,] 5 3
> x[2:3,2:3] <- y
> x
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA 4 2
[3,] NA 5 3
Negative subscripts, used with vectors to exclude certain elements, work
the same way with matrices:
> y
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> y[-2,]
[,1] [,2]
[1,] 1 4
[2,] 3 6
In the second command, we requested all rows of y except the second.
3.2.3 Extended Example: Image Manipulation
Image files are inherently matrices, since the pixels are arranged in rows and
columns. If we have a grayscale image, for each pixel, we store the intensity—
the brightness–of the image at that pixel. So, the intensity of a pixel in, say,
row 28 and column 88 of the image is stored in row 28, column 88 of the
matrix. For a color image, three matrices are stored, with intensities for red,
green, and blue components, but we’ll stick to grayscale here.
For our example, let’s consider an image of the Mount Rushmore
National Memorial in the United States. Let’s read it in, using the pixmap
library. (Appendix B describes how to download and install libraries.)
> library(pixmap)
> mtrush1 <- [Link]("[Link]")
> mtrush1
Pixmap image
Type : pixmapGrey
Matrices and Arrays 63