R matrices and arrays can be understood as higher-dimensional generalizations of R vectors. As with vectors, it is important in programming to distinguish matrices from the mathematical objects of the same name. Thus, in programming, matrices can simply serve for the tabular storage of numerical data, without the primary goal necessarily being the application of mathematical matrix calculus. Conversely, elementwise arithmetic operations with matrices in programming represent rather special mathematical operations such as the Hadamard product in mathematics. In this section, we primarily want to examine matrices and arrays as data containers in imperative programming with R. An introduction to matrix calculus with the same data structures is given in Chapter 9.
15.1 Matrices
Abstractly speaking, R matrices are two-dimensional, rectangular data structures of the form \[\begin{equation}
M = \begin{pmatrix}
m_{11} & m_{12} & \cdots & m_{1n_c} \\
m_{21} & m_{22} & \cdots & m_{2n_c} \\
\vdots & \vdots & \ddots & \vdots \\
m_{n_r1} & m_{n_r2} & \cdots & {m_{n_rn_c}} \\
\end{pmatrix}
\end{equation}\] The elements \(m_{ij}, i = 1,...,n_r, j = 1,...,n_c\) of the matrix are necessarily of the same data type. In the above scheme, \(n_r\) denotes the number of rows and \(n_c\) denotes the number of columns of the matrix \(M\). Each element of a matrix therefore has a row index \(i\) and a column index \(j\). Intuitively, R matrices are thus numerically indexed tables. Formally, matrices in R are atomic vectors interpreted two-dimensionally.
15.1.1 Generation
The R function matrix() is used to generate a matrix; it fills matrices with the elements of a vector. The general syntax of this function is M = matrix(v, nrow, ncol, byrow), where
v denotes a vector of length nrow\(\cdot\)ncol,
nrow denotes the desired number of rows of M,
ncol denotes the desired number of columns of M,
the logical variable byrow denotes the filling order of M.
Since, for a given length of v and a given number of rows or columns, the corresponding number of columns or rows of the matrix follows, it is only necessary to specify either nrow or ncol, as the following examples show.
matrix(c(1:12), nrow =3) # 3 x 4 matrix of the numbers 1,...,12, byrow = FALSE
Equivalently, existing matrices with the same number of columns can be concatenated rowwise with the function rbind().
A =matrix(c(1:6) , nrow =2, byrow =TRUE) # 2 x 3 matrix of the numbers 1,...,6print(A)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
B =matrix(c(7:9), nrow =1) # 1 x 3 matrix of the numbers 7,...,9print(B)
[,1] [,2] [,3]
[1,] 7 8 9
C =rbind(A,B) # rowwise concatenation of A and Bprint(C)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
15.1.2 Characterization
The familiar function typeof() can be used to output the elementary data type of a matrix:
typeof(matrix(c(1,0,0,1) , nrow =2)) # 2 x 2 double matrix
[1] "double"
typeof(matrix(c(1L,0L,0L,1L), nrow =2)) # 2 x 2 integer matrix
[1] "integer"
typeof(matrix(c(T,T,F,F) , nrow =2)) # 2 x 2 logical matrix
[1] "logical"
typeof(matrix(c("a","b","c"), nrow =1)) # 1 x 3 character matrix
[1] "character"
The number of rows or columns of a matrix can be output with the functions nrow() (number of rows) and ncol() (number of columns).
C =matrix(1:12, nrow =3) # 3 x 4 matrixnrow(C) # number of rows
[1] 3
ncol(C) # number of columns
[1] 4
15.1.3 Indexing
In general, matrix elements are indexed with a row index and a column index. The first of two matrix indices always indexes the row, and the second always indexes the column. The remaining principles of matrix indexing correspond essentially to the principles of vector indexing. One special feature is that a missing row or column index indexes all elements of the corresponding dimension.
A =matrix(c(2:7)^2, nrow =2) # 2 x 3 matrix of the numbers 2^2,...,7^2A
[,1] [,2] [,3]
[1,] 4 16 36
[2,] 9 25 49
A[1,3] # element in row 1, column 3 of A [36]
[1] 36
A[2,2] # element in row 2, column 2 of A [25]
[1] 25
A[2,] # all elements of row 2 [9,25,49]
[1] 9 25 49
A[,3] # all elements of column 3 [36,49]
[1] 36 49
A[1:2,1:2] # submatrix of the first two rows and columns
[,1] [,2]
[1,] 4 16
[2,] 9 25
A[A>10] # elements of A greater than 10 [16,25,36,49]
[1] 16 25 36 49
A[1,c(F,F,T)] # element in row 1, column 3 of A [36]
[1] 36
15.1.4 Arithmetic
If one applies unary arithmetic operators and functions to matrices, these are evaluated elementwise, as with vectors.
A =matrix(c(1:4), nrow =2) # 2 x 2 matrix of the numbers 1,2,3,4A
[,1] [,2]
[1,] 1 3
[2,] 2 4
B = A^2# result B[i,j] = A[i,j]^2, 1 <= i,j <= 2B
[,1] [,2]
[1,] 1 9
[2,] 4 16
C =sqrt(B) # result C[i,j] = sqrt(A[i,j]^2), 1 <= i,j <= 2C
[,1] [,2]
[1,] 1 3
[2,] 2 4
D =exp(A) # result D[i,j] = exp(A[i,j]), 1 <= i,j <= 2D
Like vectors, matrices with identical numbers of rows and columns can be linked elementwise with the binary arithmetic operators +, -, *, and /. The following examples illustrate this:
A =matrix(c(1:4), nrow =2) # 2 x 2 matrix of the numbers 1,2,3,4A
[,1] [,2]
[1,] 1 3
[2,] 2 4
B =matrix(c(5:8), nrow =2) # 2 x 2 matrix of the numbers 5,6,7,8B
[,1] [,2]
[1,] 5 7
[2,] 6 8
C = A + B # result C[i,j] = A[i,j] + B[i,j], 1 <= i,j <= 2C
[,1] [,2]
[1,] 6 10
[2,] 8 12
D = A * B # result D[i,j] = A[i,j] * B[i,j], 1 <= i,j <= 2D
[,1] [,2]
[1,] 5 21
[2,] 12 32
In addition, R matrices can be used for computations in the sense of matrix calculus from linear algebra. We show only a few examples here; a detailed presentation of the mathematical principles and their R implementation can be found in Chapter 9.
C = A %*% B # 2 x 2 matrix productC
[,1] [,2]
[1,] 23 31
[2,] 34 46
A_T =t(A) # transposition of AA_T
[,1] [,2]
[1,] 1 2
[2,] 3 4
A_inv =solve(A) # inverse of AA_inv
[,1] [,2]
[1,] -2 1.5
[2,] 1 -0.5
A_det =det(A) # determinant of AA_det
[1] -2
15.1.5 Attributes
Formally, matrices are atomic vectors with a dim attribute.
A =matrix(1:12, nrow =4 ) # 4 x 3 matrixattributes(A) # call the attributes of A
$dim
[1] 4 3
As with vectors, one can also give names to matrix elements, although this is rather unusual for matrices as well. Specifically, the functions rownames() and colnames() define the matrix attribute dimnames.
rownames(A) =c("P1","P2","P3","P4") # naming the rows of Acolnames(A) =c("Age", "Hgt", "Wgt") # naming the columns of AA # matrix with attribute dimnames
R arrays are \(d\)-dimensional, hyperrectangular data structures. Intuitively, arrays can be understood as the generalization of matrices to more than two dimensions. For \(d = 1\), an array corresponds to a vector; for \(d = 2\), an array corresponds to a matrix. As with vectors and matrices, the elements of an array must be of the same data type. Arrays are characterized by how many elements \(d_i, i = 1,...,d\) the \(i\)-th dimension can represent. Each element of an array is indexed by a \(d\)-dimensional index \(i_1,i_2,...,i_d\).
15.2.1 Generation
Analogously to the function matrix(), the function array() is used to fill an array with vector elements. The general syntax of this function is A = array(v, dim), where v is a vector of array data and dim is a vector of integer values that represents the maximal indices in each of the length(dim) dimensions of the array. For example, the following command generates a \(2 \times 2 \times 3\) array.
A =array(1:12, dim =c(2,2,3)) # 2 x 2 x 3 array of the numbers 1,...,12A
Three-dimensional arrays can be imagined intuitively as matrices placed one behind another in space. The third dimension then represents the “pages” of the array. However, when working with higher-dimensional arrays, it is useful to try to detach oneself from spatial conceptions of arrays and instead understand arrays as data containers whose elements can be addressed uniquely by their indices.
15.2.2 Characterization
The length() function outputs the number of elements of an array.
A =array(1:12, dim =c(2,2,3)) # 2 x 2 x 3 array of the numbers 1,...,12length(A) # number of elements of the array
[1] 12
The function typeof() outputs the elementary data type of an array:
typeof(A) # type of the array
[1] "integer"
The function dim() outputs the dimensions of an array:
dim(A) # dimension of the array
[1] 2 2 3
15.2.3 Indexing
Indexing of arrays is analogous to vector and matrix indexing, with the difference that three or more indices are needed to index an array element.
A =array(1:12, dim =c(2,2,3)) # 2 x 2 x 3 array of the numbers 1,...,12a_223 = A[2,2,3] # array element with index address [2,2,3] (12)
15.2.4 Arithmetic
As with vectors and matrices, unary arithmetic operators are evaluated elementwise for arrays. Likewise, binary arithmetic operators are evaluated elementwise for arrays of identical dimensionality.
A =array(1:4, dim =c(1,2,2)) # 1 x 2 x 2 array of the numbers 1,...,4A
, , 1
[,1] [,2]
[1,] 1 2
, , 2
[,1] [,2]
[1,] 3 4
B =array(5:8, dim =c(1,2,2)) # 1 x 2 x 2 array of the numbers 5,...,8B