R Matrix

In this article, you will learn to work with matrices in R Programming and also learn to create and modify matrices, and access matrix elements.

Matrix is a two dimensional data structure in R programming.

Matrix is similar to vector but additionally contains the dimension attribute. All attributes of an object can be checked with the attributes() function (dimension can be checked directly with the dim() function).

We can check if a variable is a matrix or not with the class() function.


How to create a matrix in R programming?

A matrix can be created using the matrix() function.

Dimension of the matrix can be defined by passing appropriate values for arguments nrow and ncol.

Providing value for both dimensions is not necessary. If one of the dimensions is provided, the other is inferred from the length of the data.

matrix(1:9, nrow = 3, ncol = 3)

Output

[,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

Same result is obtained by providing only one dimension. That is:

matrix(1:9, nrow = 3)

Output

[,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

We can see that the matrix is filled column-wise. This can be reversed to row-wise filling by passing TRUE to the argument byrow.

# fill matrix row-wise
matrix(1:9, nrow=3, byrow=TRUE)

Output

[,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

In all cases, however, a matrix is stored in column-major order internally as we will see in the subsequent sections.

It is possible to name the rows and columns of matrix during creation by passing a 2 element list to the argument dimnames:

x <- matrix(1:9, nrow = 3, dimnames = list(c("X","Y","Z"), c("A","B","C")))
x

Output

A B C
X 1 4 7
Y 2 5 8
Z 3 6 9

These names can be accessed or changed with two helpful functions colnames() and rownames().

# access column names and rownames
colnames(x)
rownames(x)

# change column names
colnames(x) <- c("C1","C2","C3")
# change row names
rownames(x) <- c("R1","R2","R3")
x

Output

[1] "A" "B" "C"
[1] "X" "Y" "Z"
C1 C2 C3
R1  1  4  7
R22  5  8
R3  3  6  9

Create Matrix Using cbind() and rbind()

Another way of creating a matrix is by using functions cbind() and rbind() as in column bind and row bind.

cbind(c(1,2,3),c(4,5,6))
rbind(c(1,2,3),c(4,5,6))

Output

[,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
[,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

Here, the cbind() function is used to combine two vectors, c(1, 2, 3) and c(4, 5, 6), by column.

The resulting matrix will have two columns, where the first column contains the elements of the first vector and the second column contains the elements of the second vector.

Similarly, the rbind() function is used to combine two vectors, c(1, 2, 3) and c(4, 5, 6), by row.

The resulting matrix will have two rows, where the first row contains the elements of the first vector and the second row contains the elements of the second vector.

Create Matrix Using dim()

Finally, you can also create a matrix from a vector by setting its dimension using dim().

x <- c(1,2,3,4,5,6)

dim(x) <- c(2,3)
x

Output

[,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

Note: We can check if a variable is a matrix or not with the class() function. For example, in the above matrix, we can check that as:

x <- c(1,2,3,4,5,6)
class(x)

dim(x) <- c(2,3)
x
class(x)

Output

[1] "numeric"
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
[1] "matrix" "array" 

How to access Elements of a matrix?

We can access elements of a matrix using the square bracket [] indexing method. Elements can be accessed as var[row, column]. Here row and column are vectors.

Let's learn various ways to access elements of a matrix.

Using integer vector as index

We specify the row numbers and column numbers as vectors and use it for indexing.

If any field inside the bracket is left blank, it selects all.

We can use negative integers to specify rows or columns to be excluded.

x <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, ncol = 3, byrow = TRUE)
# select rows 1 & 2 and columns 2 & 3
x[c(1,2),c(2,3)]    

# leaving column field blank will select entire columns
x[c(3,2),]    

#  leaving row as well as column field blank will select entire matrix
x[,]    

# select all rows except first
x[-1,]    

Output

[,1] [,2]
[1,]    2    3
[2,]    5    6
     [,1] [,2] [,3]
[1,]    7    8    9
[2,]    4    5    6
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
     [,1] [,2] [,3]
[1,]    4    5    6
[2,]    7    8    9

One thing to notice here is that, if the matrix returned after indexing is a row matrix or column matrix, the result is given as a vector. In the above example if we do:

x[1,]
class(x[1,])

We get,

Output

[1] 1 2 3
[1] "numeric"

This behavior can be avoided by using the argument drop = FALSE while indexing. If we do:

x[1,,drop=FALSE]  # now the result is a 1X3 matrix rather than a vector

class(x[1,,drop=FALSE])

Then we get,

Output

     [,1] [,2] [,3]
[1,]    1    2    3
[1] "matrix" "array"

It is possible to index a matrix with a single vector.

While indexing in such a way, it acts like a vector formed by stacking columns of the matrix one after another. The result is returned as a vector.

Using logical vector as index

Two logical vectors can be used to index a matrix. In such a situation, rows and columns where the value is TRUE is returned. These indexing vectors are recycled if necessary and can be mixed with integer vectors.

x <- matrix(c(4, 6, 1, 8, 0, 2, 3, 7, 9), nrow = 3, ncol = 3, byrow = TRUE)
x[c(TRUE,FALSE,TRUE),c(TRUE,TRUE,FALSE)]

# the 2 element logical vector is recycled to 3 element vector
x[c(TRUE,FALSE),c(2,3)]    

Output

[,1] [,2]
[1,]    4    6
[2,]    3    7
[,1] [,2]
[1,]    6    1
[2,]    7    9

It is also possible to index using a single logical vector where recycling takes place if necessary.

x[c(TRUE, FALSE)]

In the above example, the matrix x is treated as a vector formed by stacking columns of the matrix one after another, i.e., (4,6,1,8,0,2,3,7,9).

The indexing logical vector is also recycled and thus alternating elements are selected. This property is utilized for filtering of matrix elements as shown below.

# select elements greater than 5
x[x>5]    
# select even elements
x[x%%2 == 0]    

Output

[1] 6 8 7 9
[1] 4 6 8 0 2

Using character vector as index

Indexing with a character vector is possible for matrices with a named row or column. This can be mixed with integer or logical indexing.

# create a matrix with specified values and column names
x <- matrix(c(4, 6, 1, 8, 0, 2, 3, 7, 9), nrow = 3, ncol = 3, byrow = TRUE, dimnames = list(NULL, c("A", "B", "C")))

# subset the matrix by selecting the "A" column
x[,"A"]

# subset the matrix by selecting rows that are TRUE and columns "A" and "C"
x[TRUE, c("A", "C")]

# subset the matrix by selecting rows 2 to 3 and columns "A" and "C"
x[2:3, c("A", "C")]

Output

[1] 4 8 3
     A C
[1,] 4 1
[2,] 8 2
[3,] 3 9
     A C
[1,] 8 2
[2,] 3 9

How to modify a matrix in R?

We can combine the assignment operator with the above learned methods for accessing elements of a matrix to modify it. For example,

x <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, ncol = 3, byrow = TRUE)

# modify a single element
x[2,2] <- 10
x    
# modify elements less than 5
x[x<5] <- 0   
x

Output

[,1] [,2] [,3]
[1,]    1    2    3
[2,]    4   10    6
[3,]    7    8    9
[,1] [,2] [,3]
[1,]    0    0    0
[2,]    0   10    6
[3,]    7    8    9

Transpose a Matrix

A common operation with matrices is to transpose it. This can be done with the function t().

x <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, ncol = 3, byrow = TRUE)

t(x)

Output

[,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

We can add rows or columns using the rbind() and cbind() function respectively. Similarly, it can be removed through reassignment.

x <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, ncol = 3, byrow = TRUE)
# add a column
cbind(x, c(1, 2, 3))

# add a row
rbind(x,c(1,2,3))

# remove last row
x <- x[1:2,]; x 

Output

[,1] [,2] [,3] [,4]
[1,]    1    2    31
[2,]    4    5    6    2
[3,]    7    8    9    3
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]    1    2    3
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

Dimension of the matrix can be modified as well, using the dim() function.

x <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3, byrow = TRUE)
# change to 3X2 matrix
dim(x) <- c(3,2)
x

Output

[,1] [,2]
[1,]    1    5
[2,]    4    3
[3,]    2    6
Did you find this article helpful?