Lesson 4 of 14 · 10 min
Working with Data Frames
A data frame is R's version of a spreadsheet: a table with rows and columns that can hold different kinds of information at once. Almost every biological dataset you will meet, from gene expression tables to lists of patient samples, arrives as a data frame. Learning to build and inspect one is the single most useful skill in day-to-day bioinformatics.
Meet the data frame
In a data frame each row is one observation, such as a single gene, and each column is one measured variable, such as its chromosome or its expression level. Unlike a plain grid of numbers, different columns can hold different types, with text in one column and numbers in another. We build one with the data.frame() function.
genes <- data.frame(
gene = c("TP53", "BRCA1", "EGFR", "MYC"),
chromosome = c(17, 17, 7, 8),
expression = c(8.2, 5.1, 12.7, 9.4),
stringsAsFactors = FALSE
)
genes gene chromosome expression
1 TP53 17 8.2
2 BRCA1 17 5.1
3 EGFR 7 12.7
4 MYC 8 9.4
The arrow <- assigns the result to a name, here genes, so we can reuse it later. Inside data.frame() each argument becomes a column, and c() combines several values into one column. Adding stringsAsFactors = FALSE keeps the gene names as plain text rather than converting them to R's factor type, a special format R uses for categorical data; modern R already does this by default, but stating it makes the intent clear.
Inspecting a data frame
str(genes) # structure: types and a preview of every column
head(genes) # the first rows (up to 6 by default)
nrow(genes) # how many rows
ncol(genes) # how many columns'data.frame': 4 obs. of 3 variables:
$ gene : chr "TP53" "BRCA1" "EGFR" "MYC"
$ chromosome: num 17 17 7 8
$ expression: num 8.2 5.1 12.7 9.4
gene chromosome expression
1 TP53 17 8.2
2 BRCA1 17 5.1
3 EGFR 7 12.7
4 MYC 8 9.4
[1] 4
[1] 3
# The $ operator pulls out a single column by name
genes$gene
# A column is just a vector (an ordered list of values),
# so numeric functions like mean() and summary() work on it directly
mean(genes$expression)
summary(genes$expression)[1] "TP53" "BRCA1" "EGFR" "MYC"
[1] 8.85
Min. 1st Qu. Median Mean 3rd Qu. Max.
5.100 7.425 8.800 8.850 10.225 12.700
Try it yourself: Rebuild the genes data frame from the first code block, then add a new column with genes$length_kb <- c(20, 81, 188, 5). Run ncol(genes) to confirm it now reports 4 columns, then run mean(genes$length_kb) to find the average gene length in kilobases.