R Matrix

What is a Matrix?

A matrix is a collection of elements, all the same type, arranged in a two-dimensional layout.

In a nutshell, a matrix is just a vector that has two dimensions.

When using R, you will frequently encounter the four basic matrix types viz. logical, character, integer and double (often called numeric).

Create a Matrix

You can create a matrix using the matrix() function and specifying the data and the number of rows and columns to make the matrix.

Example: Create a numeric matrix

> m <- matrix(1:6, nrow=2, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

Matrix can contain character values as well.

Example: Create a character matrix

> letters <- c("a","b","c","d","e","f")
> m <- matrix(letters, nrow=2, ncol=3)
> m
     [,1] [,2] [,3]
[1,] "a"  "c"  "e" 
[2,] "b"  "d"  "f" 

You don’t have to specify both ncol and nrow. If you specify one, R will know automatically what the other needs to be.

Example: Specify one of the ‘ncol’ or ‘nrow’

> m <- matrix(1:6, nrow=2)
> m
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

By default, the matrix is filled column-by-column. By setting byrow=TRUE you can fill the matrix row-by-row.

Example: Fill the matrix row-by-row

> m <- matrix(1:6, nrow=2, ncol=3, byrow=TRUE)
> m
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

Combine Vectors into a Matrix

You can also create a matrix using the cbind() and rbind() functions.

However, keep in mind that the vectors that are being binded must be of equal length and same type.

Example: Create a matrix using rbind() function

> v1 <- c(1, 2, 3)
> v2 <- c(4, 5, 6)
> v3 <- c(7, 8, 9)

> rbind(v1, v2, v3)
   [,1] [,2] [,3]
v1    1    2    3
v2    4    5    6
v3    7    8    9

The cbind() function does something similar. It binds the vectors as columns of a matrix.

Example: Create a matrix using cbind() function

> v1 <- c(1, 2, 3)
> v2 <- c(4, 5, 6)
> v3 <- c(7, 8, 9)

> cbind(v1, v2, v3)
     v1 v2 v3
[1,]  1  4  7
[2,]  2  5  8
[3,]  3  6  9

Change Matrix Dimension

By using the dim() function you can get the dimension of the matrix without looking at the structure.

Example: Print the dimension of a matrix

> m <- matrix(1:6, nrow=2, ncol=3)
> dim(m)
[1] 2 3

The dim() function can also be used to set the dimension of the matrix.

Example: Change the dimension of a matrix

> # a 2x3 matrix
> m <- matrix(1:6, nrow=2, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

> # make it 3x2
> dim(m) <- c(3,2)
> m
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

> # make it 1x6
> dim(m) <- c(1,6)
> m
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    2    3    4    5    6

Naming Matrix Rows and Columns

R lets you assign descriptive names to the rows and columns of a matrix. It is useful for subsetting and printing the matrix.

You can do this by assigning two element list containing row and column names to the dimnames attribute.

Example: Assign names to the rows and columns

> m <- matrix(1:6, nrow=2, ncol=3)
> dimnames(m) <- list(c("r1","r2"), c("c1","c2","c3"))
> m
   c1 c2 c3
r1  1  3  5
r2  2  4  6

You can even name the rows and columns while creating a matrix by passing dimnames argument.

Example: Naming rows and columns while matrix creation

> m <- matrix(1:6, nrow=2, ncol=3, dimnames=list(c("r1","r2"), c("c1","c2","c3")))
> m
   c1 c2 c3
r1  1  3  5
r2  2  4  6

By using the rownames() and colnames() function you can assign row names and column names separately.

Example: Assign names to the rows and columns separately

> m <- matrix(1:6, nrow=2, ncol=3)
> rownames(m) <- c("r1","r2")
> colnames(m) <- c("c1","c2","c3")
> m
   c1 c2 c3
r1  1  3  5
r2  2  4  6

You can use the same dimnames(), colnames() and rownames() functions to print column names and row names.

Example: Print column names and row names

> # print column names
> colnames(m)
[1] "c1" "c2" "c3"

> # print row names
> rownames(m)
[1] "r1" "r2"

> # print both
> dimnames(m)
[[1]]
[1] "r1" "r2"

[[2]]
[1] "c1" "c2" "c3"

Subsetting Matrices

In R, subsetting elements from matrices is much like subsetting elements from vectors.

The only difference is that you now have to specify both the row and the column position, in the order of [row, column].

Subsetting by Positive Integer

Subsetting with positive integers returns the elements at the specified positions.

Example:

> m <- matrix(1:9, nrow=3, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

> # subset for 2nd row
> m[2,]
[1] 2 5 8

> # subset for 3rd column
> m[,3]
[1] 7 8 9

> # select single element
> m[2,3]
[1] 8

> # subset for row 1 and 2 but keep all columns
> m[1:2,]
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8

> # subset for both rows and columns
> m[1:2,2:3]
     [,1] [,2]
[1,]    4    7
[2,]    5    8

> # use a vector to subset
> m[1:2,c(1, 3)]
     [,1] [,2]
[1,]    1    7
[2,]    2    8

When you subset for a single row or a column, the result will always be a vector.

To avoid this you can set the drop argument to FALSE.

Example: Preserve output as a matrix using drop=FALSE

> m <- matrix(1:9, nrow=3, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

> # simplifies the output to a vector
> m[, 2]
[1] 4 5 6
> class(m[, 2])
[1] "integer"

> # preserves output as a matrix
> m[, 2, drop = FALSE]
     [,1]
[1,]    4
[2,]    5
[3,]    6
> class(m[, 2, drop = FALSE])
[1] "matrix"

Subsetting by Negative Integer

Subsetting with negative integers will omit the elements at the specified positions.

Example:

> m <- matrix(1:9, nrow=3, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

> # omit 2nd row
> m[-2,]
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    3    6    9

> # omit 3rd column
> m[,-3]
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

> # omit 2nd row and 3rd column
> m[-2,-3]
     [,1] [,2]
[1,]    1    4
[2,]    3    6

Subsetting by Logical Values

Subsetting with logical values will return the elements where the corresponding logical value is TRUE.

Example:

> m <- matrix(1:9, nrow=3, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

> # select elements where corresponding logical value is TRUE
> m[c(TRUE,FALSE,TRUE),c(TRUE,TRUE,FALSE)]
     [,1] [,2]
[1,]    1    4
[2,]    3    6

> # select elements greater than 5
> m[m > 5]
[1] 6 7 8 9

> # select even elements
> m[m %% 2 == 0]
[1] 2 4 6 8

Subsetting by Names

Subsetting with names will return the elements having the matching names.

Example:

> m <- matrix(1:9, nrow=3, ncol=3)
> dimnames(m) <- list(c("r1","r2","r3"), c("c1","c2","c3"))

> # subset for 2nd row
> m["r2",]
c1 c2 c3 
 2  5  8

> # subset for 3rd column
> m[,"c3"]
r1 r2 r3 
 7  8  9

> # subset for 1st and 3rd row but keep all columns
> m[c("r1","r3"),]
   c1 c2 c3
r1  1  4  7
r3  3  6  9

> # select single element
> m["r2","c3"]
[1] 8

Add New Rows and Columns to Matrix

You can use the cbind() and rbind() functions for adding new rows and columns to the matrix as well.

However, keep in mind that the vectors that are being added must be of equal length and same type.

Example:

> m <- matrix(1:6, nrow=2, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

> # add new column
> cbind(m, c(7,8))
     [,1] [,2] [,3] [,4]
[1,]    1    3    5    7
[2,]    2    4    6    8

> # add new row
> rbind(m, c(10,20,30))
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
[3,]   10   20   30

Modify Matrix Elements

Modifying a matrix element is pretty straightforward.

Access the element using [] operator and simply assign a new value.

Example:

> m <- matrix(1:6, nrow=2, ncol=3)

> # moidfy single element
> m[1,2] <- 99
> m
     [,1] [,2] [,3]
[1,]    1   99    5
[2,]    2    4    6

> # modify 2nd row
> m[2,] <- c(10,20,30)
> m
     [,1] [,2] [,3]
[1,]    1   99    5
[2,]   10   20   30

> # modify elements less than 5
> m[m > 5] <- 0
> m
     [,1] [,2] [,3]
[1,]    1    0    5
[2,]    0    0    0

Matrix Operations

The most powerful feature of R is the ease of dealing with matrix operations.

Because much of statistics depend on matrix operations, R perform them in an easy and optimized way:

  • Matrix transpose
  • Creating an identity matrix
  • Scalar multiple of a matrix
  • Matrix addition and subtraction
  • Matrix multiplication
  • Matrix inversion

Matrix Transpose

To transpose a matrix, use t() function.

The transpose of a matrix is simply a flipped version of the original matrix obtained by switching rows with columns.

Example:

> m <- matrix(1:6, nrow=2, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
> t(m)
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6

Creating an Identity Matrix

You can create an identity matrix using the diag() function.

The behavior of diag() depends on what argument you pass.

If you pass a single positive integer, then diag() will create an identity matrix of that dimension.

Example: Create a 3×3 identity matrix

> diag(3)
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1

If you pass a matrix, diag() will return the diagonal elements of the matrix.

Example: Return diagonal elements of the matrix

> m <- matrix(1:9, nrow=3, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
> diag(m)
[1] 1 5 9

Scalar Multiple of a Matrix

When you multiply a matrix by a scalar value (a single number), every individual element is multiplied by that value.

Example: Multiply each matrix element by 10

> m <- matrix(1:6, nrow=2, ncol=3)
> m * 10
     [,1] [,2] [,3]
[1,]   10   30   50
[2,]   20   40   60

Matrix Addition and Subtraction

R performs addition or subtraction of two matrices of equal size in an element-wise manner.

Meaning, corresponding elements are added or subtracted from one another, depending on the operation.

Example: Add and subtract two matrices

> m1 <- matrix(1:6, nrow=2, ncol=3)
> m1
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

> m2 <- matrix(-6:-1, nrow=2, ncol=3)
> m2
     [,1] [,2] [,3]
[1,]   -6   -4   -2
[2,]   -5   -3   -1

> # addition
> m1 + m2
     [,1] [,2] [,3]
[1,]   -5   -1    3
[2,]   -3    1    5

> # subtraction
> m1 - m2
     [,1] [,2] [,3]
[1,]    7    7    7
[2,]    7    7    7

Matrix Multiplication

Unlike scalar multiplication, matrix multiplication is not a simple element-by-element calculation, and the standard * operator cannot be used.

Instead, you must use R’s matrix product operator %*%.

Example: Multiply two matrices

> m1 <- matrix(1:6, nrow=2, ncol=3)
> m1
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

> m2 <- matrix(1:6, nrow=3, ncol=2)
> m2
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

> m1 %*% m2
     [,1] [,2]
[1,]   22   49
[2,]   28   64

Matrix Inversion

The inverse of a matrix can be calculated by using the solve() function.

Example: Calculate the inverse of a matrix

> m <- matrix(1:4, nrow=2, ncol=2)
> m
     [,1] [,2]
[1,]    1    3
[2,]    2    4

> solve(m)
     [,1] [,2]
[1,]   -2  1.5
[2,]    1 -0.5

Matrix Length

You can find the total number of values in a matrix using the length() function.

Example: Find the total number of values in a matrix

> m <- matrix(1:6, nrow=2, ncol=3)
> length(m)
[1] 6