R - Matrices
R - Matrices: A Modern Approach
Section titled “R - Matrices: A Modern Approach”Matrices are fundamental R objects that arrange elements in a two-dimensional rectangular grid. A key characteristic is that all elements within a matrix must be of the same atomic type (e.g., all numeric, all character). While you can create character or logical matrices, their primary use in data analysis is for storing numeric data for mathematical computations.
In modern R, especially within the tidyverse ecosystem, the tibble or data.frame is often preferred for general data storage because it allows columns of different types. Matrices remain essential for linear algebra, statistical modeling, and high-performance computing tasks.
A matrix is created using the matrix() function.
Syntax
Section titled “Syntax”The basic syntax for creating a matrix in R is:
matrix(data, nrow, ncol, byrow = FALSE, dimnames = NULL)Description of the parameters:
data: The input vector that populates the matrix.nrow: The number of rows.ncol: The number of columns.byrow: A logical value. IfTRUE, the matrix is filled row by row. IfFALSE(the default), it’s filled column by column.dimnames: An optional list of two vectors to name the rows and columns.
Example: Creating a Matrix
Section titled “Example: Creating a Matrix”Let’s create a few matrices to see how the arguments work. We’ll use modern R styling, such as the <- assignment operator.
# By default, R fills matrices by column.# Let's create a 4x3 matrix.mat_by_col <- matrix(data = 3:14, nrow = 4)print(mat_by_col)
# To fill by row, set byrow = TRUE.mat_by_row <- matrix(data = 3:14, nrow = 4, byrow = TRUE)print(mat_by_row)
# We can also add names for clarity.row_names <- paste0("row_", 1:4)col_names <- paste0("col_", 1:3)
named_mat <- matrix( data = 3:14, nrow = 4, byrow = TRUE, dimnames = list(row_names, col_names))print(named_mat)When we execute the above code, it produces the following result:
# Output for mat_by_col (filled by column) [,1] [,2] [,3][1,] 3 7 11[2,] 4 8 12[3,] 5 9 13[4,] 6 10 14
# Output for mat_by_row (filled by row) [,1] [,2] [,3][1,] 3 4 5[2,] 6 7 8[3,] 9 10 11[4,] 12 13 14
# Output for named_mat col_1 col_2 col_3row_1 3 4 5row_2 6 7 8row_3 9 10 11row_4 12 13 14Accessing Elements of a Matrix
Section titled “Accessing Elements of a Matrix”You can access elements, rows, or columns using square bracket notation [row, column]. Leaving an index blank selects all elements in that dimension.
# Let's use our named_mat from the previous example
# Access the element at the 1st row, 3rd columnprint(named_mat[1, 3])
# You can also use names if they existprint(named_mat["row_1", "col_3"])
# Access the entire 4th rowprint(named_mat[4, ])
# Access the entire 2nd columnprint(named_mat[, 2])Executing the above code produces:
[1] 5[1] 5col_1 col_2 col_3 12 13 14row_1 row_2 row_3 row_4 4 7 10 13Matrix Computations
Section titled “Matrix Computations”Mathematical operations on matrices are a core strength of R. It’s crucial to understand the difference between element-wise operations and true matrix algebra.
Element-Wise Operations (+, -, *, /)
Section titled “Element-Wise Operations (+, -, *, /)”Standard arithmetic operators perform calculations element by element. This requires both matrices to have the exact same dimensions.
# Create two 2x3 matricesmatrix1 <- matrix(c(3, 9, -1, 4, 2, 6), nrow = 2)matrix2 <- matrix(c(5, 2, 0, 9, 3, 4), nrow = 2)
# Element-wise additionadd_result <- matrix1 + matrix2cat("Result of addition:\n")print(add_result)
# Element-wise multiplication# THIS IS NOT MATRIX MULTIPLICATION!mult_result <- matrix1 * matrix2cat("\nResult of element-wise multiplication:\n")print(mult_result)The output clearly shows each corresponding element being operated on:
Result of addition: [,1] [,2] [,3][1,] 8 -1 5[2,] 11 13 10
Result of element-wise multiplication: [,1] [,2] [,3][1,] 15 0 6[2,] 18 36 24True Matrix Multiplication (%*%)
Section titled “True Matrix Multiplication (%*%)”For true matrix multiplication according to the rules of linear algebra, you must use the %*% operator. The inner dimensions must match (i.e., the number of columns in the first matrix must equal the number of rows in the second).
# Create compatible matrices for multiplication# matrix_A is 2x3matrix_A <- matrix(1:6, nrow = 2, byrow = TRUE)# [,1] [,2] [,3]# [1,] 1 2 3# [2,] 4 5 6
# matrix_B is 3x2matrix_B <- matrix(7:12, nrow = 3, byrow = TRUE)# [,1] [,2]# [1,] 7 8# [2,] 9 10# [3,] 11 12
# The result will be a 2x2 matrixmatrix_prod <- matrix_A %*% matrix_Bcat("Result of true matrix multiplication (2x3 %*% 3x2):\n")print(matrix_prod)Executing this demonstrates correct matrix multiplication:
Result of true matrix multiplication (2x3 %*% 3x2): [,1] [,2][1,] 58 64[2,] 139 154Common Pitfalls and Best Practices
Section titled “Common Pitfalls and Best Practices”- Element-wise vs. Matrix Multiplication: Always remember to use
%*%for linear algebra multiplication. Using*is a very common error that leads to incorrect results. - Dimension Mismatch: R will throw an error if you try to perform operations on matrices with incompatible dimensions. Always check
dim()before operations. - Data Homogeneity: Remember that a matrix can only hold one data type. If you mix types (e.g., numbers and text), R will coerce all elements to the least restrictive type (usually character), which can prevent mathematical operations.
- When to use a Matrix: Use matrices for mathematical tasks. For general data storage and manipulation (e.g., a table of customer data with names, ages, and IDs), use a
tibbleordata.frame.