Dataframes

On an intuitive level, a data frame is like a matrix, with a two-dimensional rows-andcolumns structure. However, it differs from a matrix in that each column may have a different mode. For instance, one column may consist of numbers, and another column might have character strings. In this sense, just as lists are the heterogeneous analogs of vectors in one dimension, data frames are the heterogeneous analogs of matrices for two-dimensional data.

Creating Data Frames

#To begin, let’s take another look at our simple data frame example from Section 1.4.5:
kids <- c("Jack","Jill")
ages <- c(12,10)
d <- data.frame(kids,ages,stringsAsFactors=FALSE)
d # matrix-like viewpoint

The first two arguments in the call to data.frame() are clear: We wish to produce a data frame from our two vectors: kids and ages. However, that third argument, stringsAsFactors=FALSE requires more comment.

If the named argument stringsAsFactors is not specified, then by default, stringsAsFactors will be TRUE. (You can also use options() to arrange the opposite default.) This means that if we create a data frame from a character vector—in this case, kids—R will convert that vector to a factor. Because our work with character data will typically be with vectors rather than factors, we’ll set stringsAsFactors to FALSE. We’ll cover factors in Chapter 6.

Accessing Data Frames Now that we have a data frame, let’s explore a bit. Since d is a list, we can access it as such via component index values or component names:

d[[1]]
[1] "Jack" "Jill"
d$kids
[1] "Jack" "Jill"

But we can treat it in a matrix-like fashion as well. For example, we can view column 1:

d[,1]
[1] "Jack" "Jill"

This matrix-like quality is also seen when we take d apart using str():

str(d)
'data.frame':   2 obs. of  2 variables:
 $ kids: chr  "Jack" "Jill"
 $ ages: num  12 10

R tells us here that d consists of two observations—our two rows—that store data on two variables—our two columns.

Consider three ways to access the first column of our data frame above:d[[1]], d[,1], and d$kids. Of these, the third would generally considered to be clearer and, more importantly, safer than the first two. This better identifies the column and makes it less likely that you will reference the wrong column. But in writing general code—say writing R packages—matrix-like notation d[,1] is needed, and it is especially handy if you are extracting subdata frames.

Extended Example: Regression Analysis of Exam Grades Continued

getwd()
[1] "C:/Users/npenaper/Documents"
examsquiz <- read.csv("examsquiz.csv",sep=",",header=TRUE)
head(examsquiz)

Other Matrix-Like Operations

Various matrix operations also apply to data frames. Most notably and usefully, we can do filtering to extract various subdata frames of interest.

Extracting Subdata Frames As mentioned, a data frame can be viewed in row-and-column terms. In particular, we can extract subdata frames by rows or columns. Here’s an example:

examsquiz[2:5,]
examsquiz[2:5,2]
[1] 3.2 2.0 4.0 2.0
class(examsquiz[2:5,2])
[1] "numeric"
examsquiz[2:5,2,drop=FALSE]
class(examsquiz[2:5,2,drop=FALSE])
[1] "data.frame"

Note that in that second call, since examsquiz[2:5,2] is a vector, R created a vector instead of another data frame. By specifying drop=FALSE, as described for the matrix case in Section 3.6, we can keep it as a (onecolumn) data frame.

We can also do filtering. Here’s how to extract the subframe of all students whose first exam score was at least 3.8:

examsquiz[examsquiz$Exam1 >= 3.8,]

More on Treatment of NA Values Suppose the second exam score for the first student had been missing. Then we would have typed the following into that line when we were preparing the data file:

#2.0 NA 4.0

In any subsequent statistical analyses, R would do its best to cope with the missing data. However, in some situations, we need to set the option na.rm=TRUE, explicitly telling R to ignore NA values. For instance, with the missing exam score, calculating the mean score on exam 2 by calling R’s mean() function would skip that first student in finding the mean. Otherwise, R would just report NA for the mean.

Here’s a little example:

x <- c(2,NA,4)
mean(x)
[1] NA
mean(x,na.rm=TRUE)
[1] 3

In Section 2.8.2, you were introduced to the subset() function, which saves you the trouble of specifying na.rm=TRUE. You can apply it in data frames for row selection. The column names are taken in the context of the given data frame. In our example, instead of typing this:

examsquiz[examsquiz$Exam1 >= 3.8,]
subset(examsquiz,Exam1 >= 3.8)
NA
NA
LS0tDQp0aXRsZTogIlIgRGF0YWZyYW1lcyBwYXJ0IDEiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoqKkRhdGFmcmFtZXMqKg0KDQpPbiBhbiBpbnR1aXRpdmUgbGV2ZWwsIGEgZGF0YSBmcmFtZSBpcyBsaWtlIGEgbWF0cml4LCB3aXRoIGEgdHdvLWRpbWVuc2lvbmFsIHJvd3MtYW5kY29sdW1ucyBzdHJ1Y3R1cmUuIEhvd2V2ZXIsIGl0IGRpZmZlcnMgZnJvbQ0KYSBtYXRyaXggaW4gdGhhdCBlYWNoIGNvbHVtbiBtYXkgaGF2ZSBhIGRpZmZlcmVudCBtb2RlLiBGb3IgaW5zdGFuY2UsIG9uZSBjb2x1bW4gbWF5IGNvbnNpc3Qgb2YgbnVtYmVycywgYW5kIGFub3RoZXIgY29sdW1uIG1pZ2h0IGhhdmUgY2hhcmFjdGVyIHN0cmluZ3MuIEluIHRoaXMgc2Vuc2UsIGp1c3QgYXMgbGlzdHMgYXJlIHRoZSBoZXRlcm9nZW5lb3VzIGFuYWxvZ3Mgb2YgdmVjdG9ycyBpbiBvbmUgZGltZW5zaW9uLCBkYXRhDQpmcmFtZXMgYXJlIHRoZSBoZXRlcm9nZW5lb3VzIGFuYWxvZ3Mgb2YgbWF0cmljZXMgZm9yIHR3by1kaW1lbnNpb25hbCBkYXRhLg0KDQoNCioqQ3JlYXRpbmcgRGF0YSBGcmFtZXMqKg0KDQoNCmBgYHtyfQ0KI1RvIGJlZ2luLCBsZXTigJlzIHRha2UgYW5vdGhlciBsb29rIGF0IG91ciBzaW1wbGUgZGF0YSBmcmFtZSBleGFtcGxlIGZyb20gU2VjdGlvbiAxLjQuNToNCmtpZHMgPC0gYygiSmFjayIsIkppbGwiKQ0KYWdlcyA8LSBjKDEyLDEwKQ0KZCA8LSBkYXRhLmZyYW1lKGtpZHMsYWdlcyxzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQ0KZCAjIG1hdHJpeC1saWtlIHZpZXdwb2ludA0KYGBgDQoNClRoZSBmaXJzdCB0d28gYXJndW1lbnRzIGluIHRoZSBjYWxsIHRvIGRhdGEuZnJhbWUoKSBhcmUgY2xlYXI6IFdlIHdpc2ggdG8gcHJvZHVjZSBhIGRhdGEgZnJhbWUgZnJvbSBvdXIgdHdvIHZlY3RvcnM6IGtpZHMgYW5kIGFnZXMuIEhvd2V2ZXIsIHRoYXQgdGhpcmQgYXJndW1lbnQsIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UgcmVxdWlyZXMgbW9yZSBjb21tZW50LiANCg0KSWYgdGhlIG5hbWVkIGFyZ3VtZW50IHN0cmluZ3NBc0ZhY3RvcnMgaXMgbm90IHNwZWNpZmllZCwgdGhlbiBieSBkZWZhdWx0LCBzdHJpbmdzQXNGYWN0b3JzIHdpbGwgYmUgVFJVRS4gKFlvdSBjYW4gYWxzbyB1c2Ugb3B0aW9ucygpIHRvIGFycmFuZ2UgdGhlIG9wcG9zaXRlIGRlZmF1bHQuKSBUaGlzIG1lYW5zIHRoYXQgaWYgd2UgY3JlYXRlIGEgZGF0YSBmcmFtZSBmcm9tIGEgY2hhcmFjdGVyIHZlY3RvcuKAlGluIHRoaXMgY2FzZSwga2lkc+KAlFIgd2lsbCBjb252ZXJ0IHRoYXQgdmVjdG9yIHRvIGEgZmFjdG9yLiBCZWNhdXNlIG91ciB3b3JrIHdpdGggY2hhcmFjdGVyIGRhdGEgd2lsbCB0eXBpY2FsbHkgYmUgd2l0aCB2ZWN0b3JzIHJhdGhlciB0aGFuIGZhY3RvcnMsIHdl4oCZbGwgc2V0IHN0cmluZ3NBc0ZhY3RvcnMgdG8gRkFMU0UuIFdl4oCZbGwgY292ZXIgZmFjdG9ycyBpbiBDaGFwdGVyIDYuDQoNCg0KKipBY2Nlc3NpbmcgRGF0YSBGcmFtZXMqKg0KTm93IHRoYXQgd2UgaGF2ZSBhIGRhdGEgZnJhbWUsIGxldOKAmXMgZXhwbG9yZSBhIGJpdC4gU2luY2UgZCBpcyBhIGxpc3QsIHdlIGNhbiBhY2Nlc3MgaXQgYXMgc3VjaCB2aWEgY29tcG9uZW50IGluZGV4IHZhbHVlcyBvciBjb21wb25lbnQgbmFtZXM6DQoNCmBgYHtyfQ0KZFtbMV1dDQpkJGtpZHMNCmBgYA0KDQpCdXQgd2UgY2FuIHRyZWF0IGl0IGluIGEgbWF0cml4LWxpa2UgZmFzaGlvbiBhcyB3ZWxsLiBGb3IgZXhhbXBsZSwgd2UgY2FuIHZpZXcgY29sdW1uIDE6DQoNCmBgYHtyfQ0KZFssMV0NCmBgYA0KVGhpcyBtYXRyaXgtbGlrZSBxdWFsaXR5IGlzIGFsc28gc2VlbiB3aGVuIHdlIHRha2UgZCBhcGFydCB1c2luZyBzdHIoKToNCg0KYGBge3J9DQpzdHIoZCkNCmBgYA0KUiB0ZWxscyB1cyBoZXJlIHRoYXQgZCBjb25zaXN0cyBvZiB0d28gb2JzZXJ2YXRpb25z4oCUb3VyIHR3byByb3dz4oCUdGhhdCBzdG9yZSBkYXRhIG9uIHR3byB2YXJpYWJsZXPigJRvdXIgdHdvIGNvbHVtbnMuDQoNCkNvbnNpZGVyIHRocmVlIHdheXMgdG8gYWNjZXNzIHRoZSBmaXJzdCBjb2x1bW4gb2Ygb3VyIGRhdGEgZnJhbWUgYWJvdmU6ZFtbMV1dLCBkWywxXSwgYW5kIGQka2lkcy4gT2YgdGhlc2UsIHRoZSB0aGlyZCB3b3VsZCBnZW5lcmFsbHkgY29uc2lkZXJlZCB0byBiZSBjbGVhcmVyIGFuZCwgbW9yZSBpbXBvcnRhbnRseSwgc2FmZXIgdGhhbiB0aGUgZmlyc3QgdHdvLiBUaGlzIGJldHRlciBpZGVudGlmaWVzIHRoZSBjb2x1bW4gYW5kIG1ha2VzIGl0IGxlc3MgbGlrZWx5IHRoYXQgeW91IHdpbGwgcmVmZXJlbmNlIHRoZSB3cm9uZyBjb2x1bW4uIEJ1dCBpbiB3cml0aW5nIGdlbmVyYWwgY29kZeKAlHNheSB3cml0aW5nIFIgcGFja2FnZXPigJRtYXRyaXgtbGlrZQ0Kbm90YXRpb24gZFssMV0gaXMgbmVlZGVkLCBhbmQgaXQgaXMgZXNwZWNpYWxseSBoYW5keSBpZiB5b3UgYXJlIGV4dHJhY3Rpbmcgc3ViZGF0YSBmcmFtZXMuDQoNCioqRXh0ZW5kZWQgRXhhbXBsZTogUmVncmVzc2lvbiBBbmFseXNpcyBvZiBFeGFtIEdyYWRlcyBDb250aW51ZWQqKg0KDQpgYGB7cn0NCmdldHdkKCkNCmBgYA0KDQoNCmBgYHtyfQ0KZXhhbXNxdWl6IDwtIHJlYWQuY3N2KCJleGFtc3F1aXouY3N2IixzZXA9IiwiLGhlYWRlcj1UUlVFKQ0KYGBgDQoNCg0KYGBge3J9DQpoZWFkKGV4YW1zcXVpeikNCmBgYA0KDQoqKk90aGVyIE1hdHJpeC1MaWtlIE9wZXJhdGlvbnMqKg0KDQpWYXJpb3VzIG1hdHJpeCBvcGVyYXRpb25zIGFsc28gYXBwbHkgdG8gZGF0YSBmcmFtZXMuIE1vc3Qgbm90YWJseSBhbmQgdXNlZnVsbHksIHdlIGNhbiBkbyBmaWx0ZXJpbmcgdG8gZXh0cmFjdCB2YXJpb3VzIHN1YmRhdGEgZnJhbWVzIG9mIGludGVyZXN0Lg0KDQoNCkV4dHJhY3RpbmcgU3ViZGF0YSBGcmFtZXMNCkFzIG1lbnRpb25lZCwgYSBkYXRhIGZyYW1lIGNhbiBiZSB2aWV3ZWQgaW4gcm93LWFuZC1jb2x1bW4gdGVybXMuIEluIHBhcnRpY3VsYXIsIHdlIGNhbiBleHRyYWN0IHN1YmRhdGEgZnJhbWVzIGJ5IHJvd3Mgb3IgY29sdW1ucy4gSGVyZeKAmXMgYW4gZXhhbXBsZToNCg0KDQpgYGB7cn0NCmV4YW1zcXVpelsyOjUsXQ0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KZXhhbXNxdWl6WzI6NSwyXQ0KYGBgDQoNCmBgYHtyfQ0KY2xhc3MoZXhhbXNxdWl6WzI6NSwyXSkNCmBgYA0KDQpgYGB7cn0NCmV4YW1zcXVpelsyOjUsMixkcm9wPUZBTFNFXQ0KYGBgDQoNCg0KYGBge3J9DQpjbGFzcyhleGFtc3F1aXpbMjo1LDIsZHJvcD1GQUxTRV0pDQpgYGANCg0KTm90ZSB0aGF0IGluIHRoYXQgc2Vjb25kIGNhbGwsIHNpbmNlIGV4YW1zcXVpelsyOjUsMl0gaXMgYSB2ZWN0b3IsIFIgY3JlYXRlZCBhIHZlY3RvciBpbnN0ZWFkIG9mIGFub3RoZXIgZGF0YSBmcmFtZS4gQnkgc3BlY2lmeWluZyBkcm9wPUZBTFNFLCBhcyBkZXNjcmliZWQgZm9yIHRoZSBtYXRyaXggY2FzZSBpbiBTZWN0aW9uIDMuNiwgd2UgY2FuIGtlZXAgaXQgYXMgYSAob25lY29sdW1uKSBkYXRhIGZyYW1lLg0KDQpXZSBjYW4gYWxzbyBkbyBmaWx0ZXJpbmcuIEhlcmXigJlzIGhvdyB0byBleHRyYWN0IHRoZSBzdWJmcmFtZSBvZiBhbGwgc3R1ZGVudHMgd2hvc2UgZmlyc3QgZXhhbSBzY29yZSB3YXMgYXQgbGVhc3QgMy44Og0KDQoNCmBgYHtyfQ0KZXhhbXNxdWl6W2V4YW1zcXVpeiRFeGFtMSA+PSAzLjgsXQ0KYGBgDQoNCg0KKipNb3JlIG9uIFRyZWF0bWVudCBvZiBOQSBWYWx1ZXMqKg0KU3VwcG9zZSB0aGUgc2Vjb25kIGV4YW0gc2NvcmUgZm9yIHRoZSBmaXJzdCBzdHVkZW50IGhhZCBiZWVuIG1pc3NpbmcuIFRoZW4gd2Ugd291bGQgaGF2ZSB0eXBlZCB0aGUgZm9sbG93aW5nIGludG8gdGhhdCBsaW5lIHdoZW4gd2Ugd2VyZSBwcmVwYXJpbmcgdGhlIGRhdGEgZmlsZToNCg0KDQpgYGB7cn0NCiMyLjAgTkEgNC4wDQpgYGANCg0KDQpJbiBhbnkgc3Vic2VxdWVudCBzdGF0aXN0aWNhbCBhbmFseXNlcywgUiB3b3VsZCBkbyBpdHMgYmVzdCB0byBjb3BlIHdpdGggdGhlIG1pc3NpbmcgZGF0YS4gSG93ZXZlciwgaW4gc29tZSBzaXR1YXRpb25zLCB3ZSBuZWVkIHRvIHNldCB0aGUgb3B0aW9uIG5hLnJtPVRSVUUsIGV4cGxpY2l0bHkgdGVsbGluZyBSIHRvIGlnbm9yZSBOQSB2YWx1ZXMuIEZvciBpbnN0YW5jZSwgd2l0aCB0aGUgbWlzc2luZyBleGFtIHNjb3JlLCBjYWxjdWxhdGluZyB0aGUgbWVhbiBzY29yZSBvbiBleGFtIDIgYnkgY2FsbGluZyBS4oCZcyBtZWFuKCkgZnVuY3Rpb24gd291bGQgc2tpcCB0aGF0IGZpcnN0IHN0dWRlbnQgaW4gZmluZGluZyB0aGUgbWVhbi4gT3RoZXJ3aXNlLCBSIHdvdWxkIGp1c3QgcmVwb3J0IE5BIGZvciB0aGUgbWVhbi4NCg0KSGVyZeKAmXMgYSBsaXR0bGUgZXhhbXBsZToNCg0KDQpgYGB7cn0NCnggPC0gYygyLE5BLDQpDQptZWFuKHgpDQpgYGANCg0KDQpgYGB7cn0NCm1lYW4oeCxuYS5ybT1UUlVFKQ0KYGBgDQoNCkluIFNlY3Rpb24gMi44LjIsIHlvdSB3ZXJlIGludHJvZHVjZWQgdG8gdGhlIHN1YnNldCgpIGZ1bmN0aW9uLCB3aGljaCBzYXZlcyB5b3UgdGhlIHRyb3VibGUgb2Ygc3BlY2lmeWluZyBuYS5ybT1UUlVFLiBZb3UgY2FuIGFwcGx5IGl0IGluIGRhdGEgZnJhbWVzIGZvciByb3cgc2VsZWN0aW9uLiBUaGUgY29sdW1uIG5hbWVzIGFyZSB0YWtlbiBpbiB0aGUgY29udGV4dCBvZiB0aGUgZ2l2ZW4gZGF0YSBmcmFtZS4gSW4gb3VyIGV4YW1wbGUsIGluc3RlYWQgb2YgdHlwaW5nIHRoaXM6DQoNCg0KYGBge3J9DQpleGFtc3F1aXpbZXhhbXNxdWl6JEV4YW0xID49IDMuOCxdDQpgYGANCg0KDQpgYGB7cn0NCnN1YnNldChleGFtc3F1aXosRXhhbTEgPj0gMy44KQ0KDQoNCmBgYA0KDQoNCg0KDQo=