R Matrices — 2D Data Structures
Learning Objectives
By the end of this tutorial, you will be able to:
- Create matrices using
matrix(),rbind(), andcbind() - Index matrices by row, column, or both
- Perform matrix arithmetic and linear algebra
- Apply functions across rows and columns
- Understand when to use matrices vs data frames
What Is a Matrix?
A matrix is a two-dimensional array of homogeneous data (all same type). It's the workhorse of linear algebra in R.
# Create a 3x2 matrix
m <- matrix(1:6, nrow = 3, ncol = 2)
m
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# Dimensions
dim(m) # [1] 3 2
nrow(m) # [1] 3
ncol(m) # [1] 2
length(m) # [1] 6
Creating Matrices
Using matrix()
# By row (default fills by column)
matrix(1:6, nrow = 3, ncol = 2)
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# Fill by row
matrix(1:6, nrow = 3, ncol = 2, byrow = TRUE)
# [,1] [,2]
# [1,] 1 2
# [2,] 3 4
# [3,] 5 6
# From a vector
matrix(1:12, nrow = 4)
# [,1] [,2] [,3]
# [1,] 1 5 9
# [2,] 2 6 10
# [3,] 3 7 11
# [4,] 4 8 12
# With names
m <- matrix(1:6, nrow = 2, dimnames = list(c("row1", "row2"), c("col1", "col2", "col3")))
m
# col1 col2 col3
# row1 1 3 5
# row2 2 4 6
Using rbind() and cbind()
# rbind — row bind
rbind(c(1, 2, 3), c(4, 5, 6))
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# cbind — column bind
cbind(c(1, 2, 3), c(4, 5, 6))
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# From named vectors
x <- c(a = 1, b = 2, c = 3)
y <- c(a = 4, b = 5, c = 6)
cbind(x, y)
# x y
# a 1 4
# b 2 5
# c 3 6
Special Matrices
# Identity matrix
diag(3)
# [,1] [,2] [,3]
# [1,] 1 0 0
# [2,] 0 1 0
# [3,] 0 0 1
# Diagonal matrix
diag(c(1, 2, 3))
# [,1] [,2] [,3]
# [1,] 1 0 0
# [2,] 0 2 0
# [3,] 0 0 3
# Zero matrix
matrix(0, nrow = 3, ncol = 3)
# Ones matrix
matrix(1, nrow = 3, ncol = 3)
# Random matrix
matrix(rnorm(9), nrow = 3)
Indexing Matrices
m <- matrix(1:12, nrow = 3, ncol = 4)
# [,1] [,2] [,3] [,4]
# [1,] 1 4 7 10
# [2,] 2 5 8 11
# [3,] 3 6 9 12
# Single element
m[2, 3] # [1] 8
# Entire row
m[2, ] # [1] 2 5 8 11
# Entire column
m[, 3] # [1] 7 8 9
# Multiple rows
m[c(1, 3), ] # Select rows 1 and 3
# Multiple columns
m[, c(2, 4)] # Select columns 2 and 4
# Submatrix
m[1:2, 3:4] # Rows 1-2, columns 3-4
# With names
rownames(m) <- c("r1", "r2", "r3")
colnames(m) <- c("c1", "c2", "c3", "c4")
m["r2", "c3"] # [1] 8
Matrix Operations
Element-Wise Operations
A <- matrix(1:4, nrow = 2)
B <- matrix(5:8, nrow = 2)
A + B # Addition
A - B # Subtraction
A * B # Element-wise multiplication
A / B # Element-wise division
A ^ B # Element-wise power
# Scalar operations
A + 10
A * 2
Matrix Multiplication
A <- matrix(1:4, nrow = 2)
B <- matrix(5:8, nrow = 2)
# Matrix multiplication (%*%)
A %*% B
# [,1] [,2]
# [1,] 19 22
# [2,] 43 50
# Cross-product (faster for t(A) %*% A)
crossprod(A) # t(A) %*% A
# t() — transpose
t(A)
# [,1] [,2]
# [1,] 1 3
# [2,] 2 4
# solve() — inverse
M <- matrix(c(1, 2, 3, 4), nrow = 2)
solve(M)
# [,1] [,2]
# [1,] -2 1.5
# [2,] 1 -0.5
# Verify: M %*% solve(M) should be identity
M %*% solve(M)
# [,1] [,2]
# [1,] 1 0
# [2,] 0 1
Linear Algebra Functions
A <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3)
# Determinant (square matrices only)
M <- matrix(c(1, 2, 3, 4), nrow = 2)
det(M) # [1] -2
# Eigenvalues and eigenvectors
eigen(M)
# eigen() decomposition
# $values
# [1] 5.3722813 -0.3722813
# $vectors
# [,1] [,2]
# [1,] -0.4159736 -0.8245648
# [2,] -0.9093767 0.5657675
# Singular Value Decomposition
svd(A)
# QR decomposition
qr(A)
# Cholesky decomposition (positive-definite matrices)
M <- matrix(c(4, 2, 2, 3), nrow = 2)
chol(M)
# [,1] [,2]
# [1,] 2 1.0000000
# [2,] 0 1.2247449
# Apply function row-wise or column-wise
apply(A, 1, sum) # Row sums
apply(A, 2, mean) # Column means
Useful Matrix Functions
m <- matrix(1:12, nrow = 3, ncol = 4)
# Aggregate functions
rowSums(m) # Row sums
colSums(m) # Column sums
rowMeans(m) # Row means
colMeans(m) # Column means
# Apply custom function
apply(m, 1, function(x) max(x) - min(x)) # Row ranges
apply(m, 2, function(x) sum(x^2)) # Column sum of squares
# Which
which(m > 8) # Linear indices
which(m > 8, arr.ind = TRUE) # Row/column indices
# Reshape
m
t(m) # Transpose
rev(m) # Reverse order
Matrix vs Data Frame
| Feature | Matrix | Data Frame |
|---|---|---|
| Data Types | Homogeneous | Heterogeneous |
| Creation | matrix() | data.frame() |
| Indexing | m[i, j] | df[i, j] or df$col |
| Use Case | Linear algebra, math | Tabular data, statistics |
| Row/Column Names | rownames(), colnames() | rownames(), names() |
| Speed | Faster for math | Slower for math |
# Matrix — all same type
m <- matrix(1:6, nrow = 2)
class(m) # [1] "matrix" "array"
# Data frame — can mix types
df <- data.frame(name = c("Alice", "Bob"), score = c(95, 87))
class(df) # [1] "data.frame"
# Convert matrix to data frame
df <- as.data.frame(m)
# Convert data frame to matrix
m <- as.matrix(df)
Practice Exercises
Exercise 1: Matrix Calculator
Create a 3x3 matrix with values 1-9, then:
- Calculate the sum of the diagonal
- Find the determinant
- Transpose the matrix
- Multiply each element by 2
Solution
m <- matrix(1:9, nrow = 3)
m
# [,1] [,2] [,3]
# [1,] 1 4 7
# [2,] 2 5 8
# [3,] 3 6 9
# 1. Sum of diagonal
sum(diag(m)) # [1] 15
# 2. Determinant
det(m) # [1] 0 (singular matrix)
# 3. Transpose
t(m)
# 4. Multiply by 2
m * 2
Exercise 2: Row and Column Operations
Given a 4x3 matrix, find the row with the maximum sum and the column with the minimum mean.
Solution
m <- matrix(sample(1:20, 12), nrow = 4, ncol = 3)
m
# Row with maximum sum
row_sums <- rowSums(m)
names(which.max(row_sums))
# Column with minimum mean
col_means <- colMeans(m)
names(which.min(col_means))
Key Takeaways
- Matrices are 2D arrays of homogeneous data
- Use
matrix(),rbind(),cbind()to create matrices - Index with
m[row, col]— leave blank for all rows/columns %*%is matrix multiplication,*is element-wiseapply()applies functions across rows or columnssolve()gives the inverse,det()the determinant,eigen()eigenvalues- Use matrices for linear algebra, data frames for tabular data
Next: Learn about R Data Frames — R's most important data structure.