Matrices

(Sections 7.1 - 7.3)

The Big Picture

Computer Science at GC: the Topics

  • Basic Programming
    • CSC 115
    • CSC 215
  • Data Analysis
    • CSC 303 Fundamentals of Data Computing
    • CSC 400 Modern Data Science
  • Web Design/Programming
    • CSC 324 Web Programming
  • Data Analysis and the Web Combined
    • increasing integration as you proceed through 115, 215, 303 and 400

Computer Science at GC: the Tools

  • R: a programming language that excels in data analysis
    • begun in CSC 115
  • shiny: an R package for programming web apps
    • CSC 215 and CSC 400
  • git and GitHub: version control and collaborative programming
    • CSC 324
  • JavaScript: a programming language for web browsers (and more!)
    • CSC 324
  • SQL: a programming language for querying and managing databases
    • CSC 400

R for Data Analysis

Since R was designed for data analysis, it supports data structures that make data analysis easier.

In this Chapter we learn about one such data structure: data frames.

Unlike the vectors you have met so far, data frames are two-dimensional.

So, as a warm-up, we look at another two-dimensional data structure in R: the matrix.

Introduction to Matrices

What a Matrix Is

Matrix

An atomic vector that has two additional attributes: a number of rows and a number of columns.

Creating a Matrix

Take a vector and give it those two extra attributes, using the matrix() function.:

numbers <- 1:24  # this is an ordinary atomic vector
numbersMat <- matrix(numbers, nrow = 6, ncol = 4)  # make a matrix
numbersMat
     [,1] [,2] [,3] [,4]
[1,]    1    7   13   19
[2,]    2    8   14   20
[3,]    3    9   15   21
[4,]    4   10   16   22
[5,]    5   11   17   23
[6,]    6   12   18   24

Alternative

You could just specify one of the dimensions:

numbersMat <- matrix(numbers, nrow = 6)

Fill in Across Rows

What if you want to “write in” the elements by row, instead of down columns?

matrix(numbers, nrow = 6, byrow = TRUE)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
[4,]   13   14   15   16
[5,]   17   18   19   20
[6,]   21   22   23   24

Any Data Type Allowed

Matrices do not have to be numerical:

creatures <- c("Dorothy", "Lion", "Scarecrow", "Oz",
               "Toto", "Boq")
matrix(creatures, ncol = 2)
     [,1]        [,2]  
[1,] "Dorothy"   "Oz"  
[2,] "Lion"      "Toto"
[3,] "Scarecrow" "Boq" 

Spreading Out a Matrix

You can convert a matrix to a regular vector:

as.vector(numbersMat)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Naming Rows and Columns

You can give your matrix row and column-names!

rownames(numbersMat) <- letters[1:6]  # six rows
colnames(numbersMat) <- LETTERS[1:4]  # four columns
numbersMat
  A  B  C  D
a 1  7 13 19
b 2  8 14 20
c 3  9 15 21
d 4 10 16 22
e 5 11 17 23
f 6 12 18 24

Matrix Indexing

Using Indices

You subset matrices with the [ operator.

To get the value at the second row and third column:

numbersMat[2,3]
[1] 14

The row and column numbers are called indices.

General Form

Suppose that vector1 and vector2 are numerical vectors. Then

numbersMat[vector1, vector2]

gives you a sub-matrix of the elements in rows and columns covered by combinations of values in the two vectors.

Example

The sub-matrix consisting of elements in

  • the second or fourth rows, and
  • the first, second or third columns

can be gotten like this:

numbersMat[c(2,4), 1:3]
  A  B  C
b 2  8 14
d 4 10 16

Example

The sub-matrix consisting of elements in

  • the second or fourth rows, and
  • any of the four columns

can be gotten like this:

numbersMat[c(2,4), ]  # just leave "columns" part blank
  A  B  C  D
b 2  8 14 20
d 4 10 16 22

Example

The sub-matrix consisting of elements in

  • any of the six rows and
  • the first, second or third columns

can be gotten like this:

numbersMat[, 1:3]  # just leave "rows" part blank
  A  B  C
a 1  7 13
b 2  8 14
c 3  9 15
d 4 10 16
e 5 11 17
f 6 12 18

A (Slight) Exception

If you only want to pick from one row (or one column) then you don’t get a matrix back.

numbersMat[1, ]  # just the first row
 A  B  C  D 
 1  7 13 19 

The result is a vector, not a matrix. (Usually that’s what you want.)

What If I WANT a Matrix Back?

Set the drop parameter to FALSE:

numbersMat[1, , drop = FALSE]
  A B  C  D
a 1 7 13 19

Caution: Watch Indices

Don’t ask for rows or columns that your matrix does not have:

numbersMat[2:3, 5]  # oops!  (only four columns)
Error in numbersMat[2:3, 5] : subscript out of bounds

Subsetting with Names …

… works just as with ordinary vectors:

numbersMat[c("a", "c"), LETTERS[2:3]]
  B  C
a 7 13
c 9 15

Logical Subsetting …

… works just as with ordinary vectors:

rowNumbers <- 1:6
rowIsEven <- rowNumbers %% 2 == 0
rowIsEven
[1] FALSE  TRUE FALSE  TRUE FALSE  TRUE
numbersMat[rowIsEven, ] # pick only the even-numbered rows
  A  B  C  D
b 2  8 14 20
d 4 10 16 22
f 6 12 18 24

Subsetting to Assign: I

numbersMat[2,3] <- 0
numbersMat
  A  B  C  D
a 1  7 13 19
b 2  8  0 20
c 3  9 15 21
d 4 10 16 22
e 5 11 17 23
f 6 12 18 24

Subsetting to Assign: II

You can assign to more than one place in a matrix:

numbersMat[2,] <- 0
numbersMat
  A  B  C  D
a 1  7 13 19
b 0  0  0  0
c 3  9 15 21
d 4 10 16 22
e 5 11 17 23
f 6 12 18 24

The 0 was recycled to make this happen!

Subsetting to Assign: III

You can assign different values to different places.

numbersMat[2,] <- c(100, 200, 300, 400)
numbersMat
    A   B   C   D
a   1   7  13  19
b 100 200 300 400
c   3   9  15  21
d   4  10  16  22
e   5  11  17  23
f   6  12  18  24

Operations on Matrices

Arithmetic Operations

Here are two 2-by-2 matrices:

mat1 <- matrix(rep(1, 4), nrow = 2)
mat2 <- matrix(rep(2, 4), nrow = 2)
mat1
     [,1] [,2]
[1,]    1    1
[2,]    1    1
mat2
     [,1] [,2]
[1,]    2    2
[2,]    2    2

Addition

Matrices add element-wise:

mat1 + mat2
     [,1] [,2]
[1,]    3    3
[2,]    3    3

Subtraction, division, etc. all work the element-wise as well.

Recycling Applies

Suppose we have:

mat <- matrix(1:4, nrow = 2)
mat
     [,1] [,2]
[1,]    1    3
[2,]    2    4

Multiply every element of mat by 2:

2 * mat
     [,1] [,2]
[1,]    2    6
[2,]    4    8

Recycling

This is the same as:

matrix(rep(2, 4), nrow = 2) * mat

Matrix Multiplication

* does not do the matrix multiplication that we do in Linear Algebra.

To learn how R does “real” matrix multiplication, study the textbook.

Logical Operations

Boolean operations apply to matrices element-wise. The result is a matrix of logical values. Consider the original matrix numbersMat:

numbersMat <- matrix(1:24, nrow = 6)

Determine which elements of numbersMat are odd:

numbersMat %% 2 == 1
      [,1]  [,2]  [,3]  [,4]
[1,]  TRUE  TRUE  TRUE  TRUE
[2,] FALSE FALSE FALSE FALSE
[3,]  TRUE  TRUE  TRUE  TRUE
[4,] FALSE FALSE FALSE FALSE
[5,]  TRUE  TRUE  TRUE  TRUE
[6,] FALSE FALSE FALSE FALSE

Logical Subsetting

We can select elements from a matrix using a Boolean operator:

numbersMat[numbersMat %% 2 == 1]
 [1]  1  3  5  7  9 11 13 15 17 19 21 23

The result is an ordinary, one-dimensional vector.