At the beginning of the chapter, I said that a matrix is just a vector but with two additional attributes: the number of rows and the number of columns. Here, we’ll take a closer look at the vector nature of matrices. Consider this example:

z <- matrix(1:8,nrow=4)
z
     [,1] [,2]
[1,]    1    5
[2,]    2    6
[3,]    3    7
[4,]    4    8
length(z)#As z is still a vector, we can query its length
[1] 8
class(z)
[1] "matrix" "array" 
dim(z)
[1] 4 2

Avoiding Unintended Dimension Reduction In the world of statistics, dimension reduction is a good thing, with many statistical procedures aimed to do it well. If we are working with, say, 10 variables and can reduce that number to 3 that still capture the essence of our data, we’re happy. However, in R, something else might merit the name dimension reduction that we may sometimes wish to avoid. Say we have a four-row matrix and extract a row from it:

z
     [,1] [,2]
[1,]    1    5
[2,]    2    6
[3,]    3    7
[4,]    4    8
r <- z[2,]
r
[1] 2 6

This seems innocuous, but note the format in which R has displayed r. It’s a vector format, not a matrix format. In other words, r is a vector of length 2, rather than a 1-by-2 matrix. We can confirm this in a couple of ways:

attributes(z)
$dim
[1] 4 2
attributes(r)
NULL
str(z)
 int [1:4, 1:2] 1 2 3 4 5 6 7 8
str(r)
 int [1:2] 2 6

Fortunately, R has a way to suppress this dimension reduction: the drop argument. Here’s an example, using the matrix z from above:

r <- z[2,, drop=FALSE]
r
     [,1] [,2]
[1,]    2    6
dim(r)
[1] 1 2
class(r)
[1] "matrix" "array" 

Naming Matrix Rows and Columns

The natural way to refer to rows and columns in a matrix is via the row and column numbers. However, you can also give names to these entities. Here’s an example:

z
     [,1] [,2]
[1,]    1    5
[2,]    2    6
[3,]    3    7
[4,]    4    8
colnames(z)
NULL
colnames(z) <- c("a","b")
z
     a b
[1,] 1 5
[2,] 2 6
[3,] 3 7
[4,] 4 8
colnames(z)
[1] "a" "b"
z[,"a"]
[1] 1 2 3 4

Higher-Dimensional Arrays

In a statistical context, a typical matrix in R has rows corresponding to observations, say on various people, and columns corresponding to variables, such as weight and blood pressure. The matrix is then a two-dimensional data structure. But suppose we also have data taken at different times, one data point per person per variable per time. Time then becomes the third dimension, in addition to rows and columns. In R, such data sets are called arrays. As a simple example, consider students and test scores. Say each test consists of two parts, so we record two scores for a student for each test. Now suppose that we have two tests, and to keep the example small, assume we have only three students. Here’s the data for the first test:

firsttest <- matrix(nrow=3,ncol=2)
firsttest[1,1] <- 46
firsttest[2,1] <- 21
firsttest[1,2] <- 30
firsttest[2,2] <- 25
firsttest[3,1] <- 50
firsttest[3,2] <- 50
firsttest
     [,1] [,2]
[1,]   46   30
[2,]   21   25
[3,]   50   50

Student 1 had scores of 46 and 30 on the first test, student 2 scored 21 and 25, and so on. Here are the scores for the same students on the second test:

secondtest <- matrix(nrow=3,ncol=2)
secondtest[1,1] <- 46
secondtest[2,1] <- 41
secondtest[1,2] <- 43
secondtest[2,2] <- 35
secondtest[3,1] <- 50
secondtest[3,2] <- 50
secondtest
     [,1] [,2]
[1,]   46   43
[2,]   41   35
[3,]   50   50

Now let’s put both tests into one data structure, which we’ll name tests. We’ll arrange it to have two “layers”—one layer per test—with three rows and two columns within each layer. We’ll store firsttest in the first layer and secondtest in the second. In layer 1, there will be three rows for the three students’ scores on the first test, with two columns per row for the two portions of a test. We use R’s array function to create the data structure:

tests <- array(data=c(firsttest,secondtest),dim=c(3,2,2))

In the argument dim=c(3,2,2), we are specifying two layers (this is the second 2), each consisting of three rows and two columns. This then becomes an attribute of the data structure:

attributes(tests)
$dim
[1] 3 2 2

Each element of tests now has three subscripts, rather than two as in the matrix case. The first subscript corresponds to the first element in the $dim vector, the second subscript corresponds to the second element in the vector, and so on. For instance, the score on the second portion of test 1 for student 3 is retrieved as follows:

tests[3,2,1]
[1] 50
tests
, , 1

     [,1] [,2]
[1,]   46   30
[2,]   21   25
[3,]   50   50

, , 2

     [,1] [,2]
[1,]   46   43
[2,]   41   35
[3,]   50   50

Just as we built our three-dimensional array by combining two matrices, we can build four-dimensional arrays by combining two or more three dimensional arrays, and so on.

LS0tDQp0aXRsZTogIkxlY3R1cmUgNF9hY3Rpdml0eSA3Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KQXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgY2hhcHRlciwgSSBzYWlkIHRoYXQgYSBtYXRyaXggaXMganVzdCBhIHZlY3RvciBidXQgd2l0aCB0d28gYWRkaXRpb25hbCBhdHRyaWJ1dGVzOiB0aGUgbnVtYmVyIG9mIHJvd3MgYW5kIHRoZSBudW1iZXIgb2YgY29sdW1ucy4gSGVyZSwgd2XigJlsbCB0YWtlIGEgY2xvc2VyIGxvb2sgYXQgdGhlIHZlY3RvciBuYXR1cmUgb2YgbWF0cmljZXMuIENvbnNpZGVyIHRoaXMgZXhhbXBsZToNCg0KYGBge3J9DQp6IDwtIG1hdHJpeCgxOjgsbnJvdz00KQ0Keg0KYGBgDQoNCg0KYGBge3J9DQpsZW5ndGgoeikjQXMgeiBpcyBzdGlsbCBhIHZlY3Rvciwgd2UgY2FuIHF1ZXJ5IGl0cyBsZW5ndGgNCmBgYA0KDQoNCmBgYHtyfQ0KY2xhc3MoeikNCmRpbSh6KQ0KYGBgDQoNCioqQXZvaWRpbmcgVW5pbnRlbmRlZCBEaW1lbnNpb24gUmVkdWN0aW9uKioNCkluIHRoZSB3b3JsZCBvZiBzdGF0aXN0aWNzLCBkaW1lbnNpb24gcmVkdWN0aW9uIGlzIGEgZ29vZCB0aGluZywgd2l0aCBtYW55IHN0YXRpc3RpY2FsIHByb2NlZHVyZXMgYWltZWQgdG8gZG8gaXQgd2VsbC4gSWYgd2UgYXJlIHdvcmtpbmcgd2l0aCwgc2F5LCAxMCB2YXJpYWJsZXMgYW5kIGNhbiByZWR1Y2UgdGhhdCBudW1iZXIgdG8gMyB0aGF0IHN0aWxsIGNhcHR1cmUgdGhlIGVzc2VuY2Ugb2Ygb3VyDQpkYXRhLCB3ZeKAmXJlIGhhcHB5LiBIb3dldmVyLCBpbiBSLCBzb21ldGhpbmcgZWxzZSBtaWdodCBtZXJpdCB0aGUgbmFtZSBkaW1lbnNpb24gcmVkdWN0aW9uIHRoYXQgd2UgbWF5IHNvbWV0aW1lcyB3aXNoIHRvIGF2b2lkLiBTYXkgd2UgaGF2ZSBhIGZvdXItcm93IG1hdHJpeCBhbmQgZXh0cmFjdCBhIHJvdyBmcm9tIGl0Og0KDQpgYGB7cn0NCnoNCmBgYA0KDQoNCmBgYHtyfQ0KciA8LSB6WzIsXQ0Kcg0KYGBgDQoNClRoaXMgc2VlbXMgaW5ub2N1b3VzLCBidXQgbm90ZSB0aGUgZm9ybWF0IGluIHdoaWNoIFIgaGFzIGRpc3BsYXllZCByLiBJdOKAmXMgYSB2ZWN0b3IgZm9ybWF0LCBub3QgYSBtYXRyaXggZm9ybWF0LiBJbiBvdGhlciB3b3JkcywgciBpcyBhIHZlY3RvciBvZiBsZW5ndGggMiwgcmF0aGVyIHRoYW4gYSAxLWJ5LTIgbWF0cml4LiBXZSBjYW4gY29uZmlybSB0aGlzIGluIGEgY291cGxlIG9mIHdheXM6DQoNCmBgYHtyfQ0KYXR0cmlidXRlcyh6KQ0KYXR0cmlidXRlcyhyKQ0Kc3RyKHopDQpzdHIocikNCmBgYA0KDQoNCkZvcnR1bmF0ZWx5LCBSIGhhcyBhIHdheSB0byBzdXBwcmVzcyB0aGlzIGRpbWVuc2lvbiByZWR1Y3Rpb246IHRoZSBkcm9wIGFyZ3VtZW50LiBIZXJl4oCZcyBhbiBleGFtcGxlLCB1c2luZyB0aGUgbWF0cml4IHogZnJvbSBhYm92ZToNCg0KYGBge3J9DQpyIDwtIHpbMiwsIGRyb3A9RkFMU0VdDQpyDQpgYGANCg0KYGBge3J9DQpkaW0ocikNCmNsYXNzKHIpDQpgYGANCioqTmFtaW5nIE1hdHJpeCBSb3dzIGFuZCBDb2x1bW5zKioNCg0KVGhlIG5hdHVyYWwgd2F5IHRvIHJlZmVyIHRvIHJvd3MgYW5kIGNvbHVtbnMgaW4gYSBtYXRyaXggaXMgdmlhIHRoZSByb3cgYW5kIGNvbHVtbiBudW1iZXJzLiBIb3dldmVyLCB5b3UgY2FuIGFsc28gZ2l2ZSBuYW1lcyB0byB0aGVzZSBlbnRpdGllcy4gSGVyZeKAmXMgYW4gZXhhbXBsZToNCg0KDQpgYGB7cn0NCnoNCmBgYA0KDQpgYGB7cn0NCmNvbG5hbWVzKHopDQpgYGANCg0KDQpgYGB7cn0NCmNvbG5hbWVzKHopIDwtIGMoImEiLCJiIikNCmBgYA0KDQoNCg0KYGBge3J9DQp6DQpjb2xuYW1lcyh6KQ0KYGBgDQoNCg0KYGBge3J9DQp6WywiYSJdDQpgYGANCg0KKipIaWdoZXItRGltZW5zaW9uYWwgQXJyYXlzKioNCg0KSW4gYSBzdGF0aXN0aWNhbCBjb250ZXh0LCBhIHR5cGljYWwgbWF0cml4IGluIFIgaGFzIHJvd3MgY29ycmVzcG9uZGluZyB0byBvYnNlcnZhdGlvbnMsIHNheSBvbiB2YXJpb3VzIHBlb3BsZSwgYW5kIGNvbHVtbnMgY29ycmVzcG9uZGluZyB0byB2YXJpYWJsZXMsIHN1Y2ggYXMgd2VpZ2h0IGFuZCBibG9vZCBwcmVzc3VyZS4gVGhlIG1hdHJpeCBpcyB0aGVuIGEgdHdvLWRpbWVuc2lvbmFsIGRhdGEgc3RydWN0dXJlLiBCdXQgc3VwcG9zZSB3ZSBhbHNvIGhhdmUgZGF0YSB0YWtlbiBhdCBkaWZmZXJlbnQgdGltZXMsIG9uZSBkYXRhIHBvaW50IHBlciBwZXJzb24gcGVyIHZhcmlhYmxlIHBlciB0aW1lLiBUaW1lIHRoZW4gYmVjb21lcyB0aGUgdGhpcmQgZGltZW5zaW9uLCBpbiBhZGRpdGlvbiB0byByb3dzIGFuZCBjb2x1bW5zLiBJbiBSLCBzdWNoIGRhdGEgc2V0cyBhcmUgY2FsbGVkIGFycmF5cy4gQXMgYSBzaW1wbGUgZXhhbXBsZSwgY29uc2lkZXIgc3R1ZGVudHMgYW5kIHRlc3Qgc2NvcmVzLiBTYXkgZWFjaCB0ZXN0IGNvbnNpc3RzIG9mIHR3byBwYXJ0cywgc28gd2UgcmVjb3JkIHR3byBzY29yZXMgZm9yIGEgc3R1ZGVudCBmb3IgZWFjaCB0ZXN0LiBOb3cNCnN1cHBvc2UgdGhhdCB3ZSBoYXZlIHR3byB0ZXN0cywgYW5kIHRvIGtlZXAgdGhlIGV4YW1wbGUgc21hbGwsIGFzc3VtZSB3ZSBoYXZlIG9ubHkgdGhyZWUgc3R1ZGVudHMuIEhlcmXigJlzIHRoZSBkYXRhIGZvciB0aGUgZmlyc3QgdGVzdDoNCg0KYGBge3J9DQpmaXJzdHRlc3QgPC0gbWF0cml4KG5yb3c9MyxuY29sPTIpDQpmaXJzdHRlc3RbMSwxXSA8LSA0Ng0KZmlyc3R0ZXN0WzIsMV0gPC0gMjENCmZpcnN0dGVzdFsxLDJdIDwtIDMwDQpmaXJzdHRlc3RbMiwyXSA8LSAyNQ0KZmlyc3R0ZXN0WzMsMV0gPC0gNTANCmZpcnN0dGVzdFszLDJdIDwtIDUwDQoNCmBgYA0KDQoNCmBgYHtyfQ0KZmlyc3R0ZXN0DQpgYGANCg0KDQpTdHVkZW50IDEgaGFkIHNjb3JlcyBvZiA0NiBhbmQgMzAgb24gdGhlIGZpcnN0IHRlc3QsIHN0dWRlbnQgMiBzY29yZWQgMjEgYW5kIDI1LCBhbmQgc28gb24uIEhlcmUgYXJlIHRoZSBzY29yZXMgZm9yIHRoZSBzYW1lIHN0dWRlbnRzIG9uIHRoZSBzZWNvbmQgdGVzdDoNCg0KYGBge3J9DQpzZWNvbmR0ZXN0IDwtIG1hdHJpeChucm93PTMsbmNvbD0yKQ0Kc2Vjb25kdGVzdFsxLDFdIDwtIDQ2DQpzZWNvbmR0ZXN0WzIsMV0gPC0gNDENCnNlY29uZHRlc3RbMSwyXSA8LSA0Mw0Kc2Vjb25kdGVzdFsyLDJdIDwtIDM1DQpzZWNvbmR0ZXN0WzMsMV0gPC0gNTANCnNlY29uZHRlc3RbMywyXSA8LSA1MA0KYGBgDQoNCg0KYGBge3J9DQpzZWNvbmR0ZXN0DQpgYGANCg0KTm93IGxldOKAmXMgcHV0IGJvdGggdGVzdHMgaW50byBvbmUgZGF0YSBzdHJ1Y3R1cmUsIHdoaWNoIHdl4oCZbGwgbmFtZSB0ZXN0cy4gV2XigJlsbCBhcnJhbmdlIGl0IHRvIGhhdmUgdHdvIOKAnGxheWVyc+KAneKAlG9uZSBsYXllciBwZXIgdGVzdOKAlHdpdGggdGhyZWUgcm93cyBhbmQgdHdvIGNvbHVtbnMgd2l0aGluIGVhY2ggbGF5ZXIuIFdl4oCZbGwgc3RvcmUgZmlyc3R0ZXN0IGluIHRoZSBmaXJzdCBsYXllciBhbmQgc2Vjb25kdGVzdCBpbiB0aGUgc2Vjb25kLiBJbiBsYXllciAxLCB0aGVyZSB3aWxsIGJlIHRocmVlIHJvd3MgZm9yIHRoZSB0aHJlZSBzdHVkZW50c+KAmSBzY29yZXMgb24gdGhlIGZpcnN0IHRlc3QsIHdpdGggdHdvIGNvbHVtbnMgcGVyIHJvdyBmb3IgdGhlIHR3byBwb3J0aW9ucyBvZiBhIHRlc3QuIFdlIHVzZSBS4oCZcyBhcnJheSBmdW5jdGlvbiB0byBjcmVhdGUgdGhlIGRhdGEgc3RydWN0dXJlOg0KDQpgYGB7cn0NCnRlc3RzIDwtIGFycmF5KGRhdGE9YyhmaXJzdHRlc3Qsc2Vjb25kdGVzdCksZGltPWMoMywyLDIpKQ0KYGBgDQoNCkluIHRoZSBhcmd1bWVudCBkaW09YygzLDIsMiksIHdlIGFyZSBzcGVjaWZ5aW5nIHR3byBsYXllcnMgKHRoaXMgaXMgdGhlIHNlY29uZCAyKSwgZWFjaCBjb25zaXN0aW5nIG9mIHRocmVlIHJvd3MgYW5kIHR3byBjb2x1bW5zLiBUaGlzIHRoZW4gYmVjb21lcyBhbiBhdHRyaWJ1dGUgb2YgdGhlIGRhdGEgc3RydWN0dXJlOg0KDQpgYGB7cn0NCmF0dHJpYnV0ZXModGVzdHMpDQpgYGANCg0KRWFjaCBlbGVtZW50IG9mIHRlc3RzIG5vdyBoYXMgdGhyZWUgc3Vic2NyaXB0cywgcmF0aGVyIHRoYW4gdHdvIGFzIGluIHRoZSBtYXRyaXggY2FzZS4gVGhlIGZpcnN0IHN1YnNjcmlwdCBjb3JyZXNwb25kcyB0byB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgJGRpbSB2ZWN0b3IsIHRoZSBzZWNvbmQgc3Vic2NyaXB0IGNvcnJlc3BvbmRzIHRvIHRoZSBzZWNvbmQgZWxlbWVudCBpbiB0aGUgdmVjdG9yLCBhbmQgc28gb24uIEZvciBpbnN0YW5jZSwgdGhlIHNjb3JlIG9uIHRoZSBzZWNvbmQgcG9ydGlvbiBvZiB0ZXN0IDEgZm9yIHN0dWRlbnQgMyBpcyByZXRyaWV2ZWQgYXMgZm9sbG93czoNCg0KYGBge3J9DQp0ZXN0c1szLDIsMV0NCmBgYA0KDQoNCmBgYHtyfQ0KdGVzdHMNCmBgYA0KDQpKdXN0IGFzIHdlIGJ1aWx0IG91ciB0aHJlZS1kaW1lbnNpb25hbCBhcnJheSBieSBjb21iaW5pbmcgdHdvIG1hdHJpY2VzLCB3ZSBjYW4gYnVpbGQgZm91ci1kaW1lbnNpb25hbCBhcnJheXMgYnkgY29tYmluaW5nIHR3byBvciBtb3JlIHRocmVlIGRpbWVuc2lvbmFsIGFycmF5cywgYW5kIHNvIG9uLg==