14  Matrices in R

NoteWhat This Chapter Covers

This chapter is a complete tour of the matrix, R’s two-dimensional, single-type container. You will learn three ways to build one (matrix(), rbind(), cbind()), how rows and columns are stored and named, the four styles of indexing ([i, j], single-bracket, negative, logical), and how to update cells or whole rows and columns. You will see how arithmetic and the summary functions rowSums(), colSums(), rowMeans(), and colMeans() treat matrices, and the handful of linear-algebra operators that matter for applied work: transpose t(), matrix multiplication %*%, the determinant det(), and the matrix inverse solve(). You will also meet apply(), R’s apply-family entry for 2-D data. By the end of this chapter you will be able to build a matrix for any rectangular, single-type problem and manipulate it with confidence.

flowchart LR
    B["Build <br> matrix() / rbind() / cbind()"] --> M["A Matrix"]
    M --> I["Index <br> [i, j], negative, logical"]
    M --> AR["Arithmetic <br> element-wise + scalar recycling"]
    M --> LA["Linear Algebra <br> t() %*% det() solve()"]
    M --> AP["Row/Column summaries <br> rowSums() apply()"]
    style B fill:#e3f2fd,stroke:#1976D2
    style M fill:#fff3e0,stroke:#F57C00
    style I fill:#e8f5e9,stroke:#388E3C
    style AR fill:#f3e5f5,stroke:#8E24AA
    style LA fill:#f3e5f5,stroke:#8E24AA
    style AP fill:#e8f5e9,stroke:#388E3C


14.1 What a Matrix Is

NoteCore Concept: A Vector with Two Dimensions

A matrix is a vector whose elements are laid out in a rectangle of rows and columns. All cells share one atomic type, which is what distinguishes a matrix from a data frame. Internally, R stores a matrix as a single vector with a dim attribute (c(nrow, ncol)), filled by column by default.

Property Matrix Data Frame
Number of dimensions 2 2
All columns one type? Yes. No.
Typical use Numeric grids, images, distances, correlations. Survey-style tabular data.
Core functions matrix(), %*%, t(), solve(). data.frame(), dplyr verbs.

14.2 Building a Matrix

Notematrix(): the Direct Constructor
Noterbind() and cbind(): Build from Vectors

rbind() stacks vectors as rows; cbind() stacks them as columns. Both functions coerce to a matrix if all inputs share a type.

NoteNaming Rows and Columns

Like vector names, row and column names are accessed and set with rownames() and colnames() (or with the single-object dimnames()).


14.3 Indexing a Matrix

Note[row, col] is the Core Pattern
NoteDropping and Keeping the Matrix Class

When you select a single row or column, R collapses the result to a plain vector by default. Pass drop = FALSE to keep a matrix.

NoteNegative and Logical Indexing
WarningCommon Mistake: Forgetting the Comma

m[1] selects the first element treating the matrix as a flat vector; m[1, ] selects the whole first row. The comma is not optional.


14.4 Modifying a Matrix

NoteReplacing Cells, Rows, and Columns
NoteAdding a Row or a Column

Use rbind() to append a new row and cbind() to append a new column.


14.5 Arithmetic on Matrices

NoteElement-Wise by Default

Arithmetic operators work cell by cell, exactly as they do on vectors. Scalars are recycled. Two matrices of the same shape combine element by element.

Warning* is Element-Wise; %*% is Matrix Multiplication

A common slip from linear-algebra textbooks is to expect A * B to perform matrix multiplication. In R, * is element-wise. Use %*% for the standard row-by-column product.


14.6 Summarising Rows and Columns

NoteFast Built-Ins
Function Returns
rowSums(m), colSums(m) One sum per row or per column.
rowMeans(m), colMeans(m) One mean per row or per column.
apply(m, 1, FUN) Apply FUN to each row.
apply(m, 2, FUN) Apply FUN to each column.
TipExpert Insight: Prefer the Built-Ins Where They Exist

rowSums() and colSums() are written in C and can be an order of magnitude faster than apply(m, 1, sum). Use them when they exist; reach for apply() for custom functions like sd or an anonymous summary.


14.7 Linear-Algebra Essentials

NoteThe Four You Will Use Most
Operator / Function Does
t(A) Transpose.
A %*% B Matrix multiplication.
det(A) Determinant (square matrices).
solve(A) Matrix inverse (for non-singular square A). solve(A, b) solves A x = b.
WarningCommon Mistake: solve(A) on a Singular Matrix

If det(A) == 0, the matrix is singular and has no inverse. solve() will error. Always check det() (or use solve(A, b) instead of computing the full inverse) for numerical stability.


14.8 Reshaping and Combining

Notedim()<- for Quick Reshapes

Assigning to dim() reshapes an existing vector or matrix. The total number of cells must stay the same.

NoteTurning a Matrix Back into a Vector

14.9 A Worked Example: A Monthly Sales Matrix

NoteA Regional-Quarterly Report

Every technique from the chapter is on display: construction with matrix(), named dimnames, index-based extraction, element-wise arithmetic for growth, rowSums() / colSums() for summaries, and cbind() / rbind() to append totals.


14.10 Summary

NoteKey Concepts at a Glance
Concept Key Takeaway
Structure Rectangular, single-type; a vector with a dim attribute.
Build matrix() for direct construction; rbind() / cbind() for assembly.
Fill order Column-major by default; use byrow = TRUE to fill by row.
Naming rownames(), colnames(), or dimnames().
Indexing [i, j] is the key form; remember the comma and drop = FALSE.
Arithmetic Element-wise by default; use %*% for matrix multiplication.
Summaries rowSums(), colSums(), rowMeans(), colMeans(), and apply().
Linear algebra t(), %*%, det(), solve() cover most applied needs.
Data frame vs matrix Same shape, different contents, use a matrix when every column shares a type.
TipApplying This in Practice

Matrices are the natural home of numeric data that fits in a rectangle: correlation structures, distance tables, monthly-regional dashboards, image pixels. When all your columns share a type and you want fast numeric work, a matrix is the right choice over a data frame. In the next chapter you will meet arrays, the n-dimensional cousin of matrices, used when two dimensions are not enough.