## C.3 Matrix Subsetting

Example matrices:

(A <- matrix(1:12, byrow=TRUE, nrow=3))
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
B <- A
dimnames(B) <- list(
c("a", "b", "c"),     # row labels
c("x", "y", "z", "w") # column labels
)
B
##   x  y  z  w
## a 1  2  3  4
## b 5  6  7  8
## c 9 10 11 12

### C.3.1 Selecting Individual Elements

Matrices are two-dimensional structures: items are aligned in rows and columns. Hence, to extract an element from a matrix, we will need two indices. Mathematically, given a matrix $$\mathbf{A}$$, $$a_{i,j}$$ stands for the element in the $$i$$-th row and the $$j$$-th column. The same in R:

A[1, 2] # 1st row, 2nd columns
## [1] 2
B["a", "y"] # using dimnames == B[1,2]
## [1] 2

### C.3.2 Selecting Rows and Columns

We will sometimes use the following notation to emphasise that a matrix $$\mathbf{A}$$ consists of $$n$$ rows or $$p$$ columns:

$\mathbf{A}=\left[ \begin{array}{c} \mathbf{a}_{1,\cdot} \\ \mathbf{a}_{2,\cdot} \\ \vdots\\ \mathbf{a}_{n,\cdot} \\ \end{array} \right] = \left[ \begin{array}{cccc} \mathbf{a}_{\cdot,1} & \mathbf{a}_{\cdot,2} & \cdots & \mathbf{a}_{\cdot,p} \\ \end{array} \right].$

Here, $$\mathbf{a}_{i,\cdot}$$ is a row vector of length $$p$$, i.e., a $$(1\times p)$$-matrix:

$\mathbf{a}_{i,\cdot} = \left[ \begin{array}{cccc} a_{i,1} & a_{i,2} & \cdots & a_{i,p} \\ \end{array} \right].$

Moreover, $$\mathbf{a}_{\cdot,j}$$ is a column vector of length $$n$$, i.e., an $$(n\times 1)$$-matrix:

$\mathbf{a}_{\cdot,j} = \left[ \begin{array}{cccc} a_{1,j} & a_{2,j} & \cdots & a_{n,j} \\ \end{array} \right]^T=\left[ \begin{array}{c} {a}_{1,j} \\ {a}_{2,j} \\ \vdots\\ {a}_{n,j} \\ \end{array} \right],$

We can extract individual rows and columns from a matrix by using the following notation:

A[1,] # 1st row
## [1] 1 2 3 4
A[,2] # 2nd column
## [1]  2  6 10
B["a",] # of course, B[1,] is still legal
## x y z w
## 1 2 3 4
B[,"y"]
##  a  b  c
##  2  6 10

Note that by extracting a single row/column, we get an atomic (one-dimensional) vector. However, we can preserve the dimensionality of the output object by passing drop=FALSE:

A[  1,    , drop=FALSE] # 1st row
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
A[   ,   2, drop=FALSE] # 2nd column
##      [,1]
## [1,]    2
## [2,]    6
## [3,]   10
B["a",    , drop=FALSE]
##   x y z w
## a 1 2 3 4
B[   , "y", drop=FALSE]
##    y
## a  2
## b  6
## c 10

Now this is what we call proper row and column vectors!

### C.3.3 Selecting Submatrices

To create a sub-block of a given matrix we pass two indexers, possibly of length greater than one:

A[1:2, c(1, 2, 4)] # rows 1,2 columns 1,2,4
##      [,1] [,2] [,3]
## [1,]    1    2    4
## [2,]    5    6    8
B[c("a", "b"), c(1, 2, 4)]
##   x y w
## a 1 2 4
## b 5 6 8
A[c(1, 3), 3]
## [1]  3 11
A[c(1, 3), 3, drop=FALSE]
##      [,1]
## [1,]    3
## [2,]   11

### C.3.4 Selecting Based on Logical Vectors and Matrices

We can also subset a matrix with a logical matrix of the same size. This always yields a (flat) vector in return.

A[A>8]
## [1]  9 10 11 12

Logical vectors can also be used as indexers:

A[c(TRUE, FALSE, TRUE),] # select 1st and 3rd row
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    9   10   11   12
A[,colMeans(A)>6] # columns with means > 6
##      [,1] [,2]
## [1,]    3    4
## [2,]    7    8
## [3,]   11   12

### C.3.5 Selecting Based on Two-Column Matrices

Lastly, note that we can also index a matrix A with a 2-column matrix I, i.e., A[I]. This allows for an easy access to A[I[1,1], I[1,2]], A[I[2,1], I[2,2]], A[I[3,1], I[3,2]], …

I <- cbind(c(1, 3, 2, 1, 2),
c(2, 3, 2, 1, 4)
)
A[I]
## [1]  2 11  6  1  8

This is exactly A[1, 2], A[3, 3], A[2, 2], A[1, 1], A[2, 4].