Lesson 5 of 17 · Week 02 · Tue Oct 6
Exploring Data Frames
Questions
- How do I get to know a new dataset?
- How do I add or remove rows and columns?
- How can I re-run my data-loading code in one step?
Objectives
- Read a CSV with a relative path and explore it with
str(),summary(),head(),tail(). - Interpret every part of
str()output. - Add columns and rows with
$,cbind()andrbind(); remove them with negative indices. - Run a whole script with
source().
The gm dataset
From here on, most examples use Gapminder data:
life expectancy, population and GDP per person by country and year. In the exercise boxes it's already loaded as a data
frame called gm: 22 countries × 4 years (1967, 1987, 2002, 2007) = 88 rows, with columns
country, continent, year, lifeExp, pop and
gdpPercap.
On your own computer, save the full dataset
(gapminder_data.csv)
into your data/ folder and read it with a relative path:
gapminder <- read.csv("data/gapminder_data.csv", stringsAsFactors = TRUE)
Everything below works the same on either. Only the sizes differ.
Adapted from Software Carpentry's “Exploring Data Frames” episode (CC BY 4.0, The Carpentries). Text, examples and exercises have been rewritten for this course.
First look
Get oriented before you analyse anything:
str(gm) # every column: its type and first values
summary(gm) # per-column summaries
dim(gm) # rows, columns (also nrow(), ncol())
colnames(gm)
head(gm) # first 6 rows; head(gm, 10) for 10
tail(gm, 3) # last 3 rows
typeof(gm) # "list" - remember, a data frame is a list of columns
length(gm) # number of columns, for the same reason
How to read str(): the first line gives the object's class and its size (obs. = rows,
variables = columns). Each line after that is one column: its name, its type
(num, int, chr, logi, or Factor w/ N levels), and its
first few values. For a factor, the numbers shown are the codes pointing at its levels.
The top and bottom rows are often the tidiest part of a file. To spot problems in the middle, look at a
random handful of rows: gm[sample(nrow(gm), 5), ].
Adding columns and rows
gm$pop_millions <- gm$pop / 1e6 # new column from existing ones
flag <- gm$lifeExp > 70
gm2 <- cbind(gm, long_lived = flag) # or bind a vector as a column
extra <- data.frame(country = "Chile", continent = "Americas", year = 2012,
lifeExp = 79.6, pop = 17.4e6, gdpPercap = 15300,
pop_millions = 17.4)
gm3 <- rbind(gm, extra) # rows must have the same columns
cbind() adds columns (lengths must match the number of rows); rbind() stacks data frames with
the same column names. With factor columns, rbind() adds any new category as a new level.
Removing rows and missing values
gm[-3, ] # everything except row 3
gm[, -6] # everything except column 6
na.omit(df) # drop every row with an NA anywhere
Be careful with na.omit(): it drops the whole row if any column is missing.
Scripts you can re-run: source()
Once your loading and cleaning code works, put it in a script (e.g. scripts/load-data.R) so you can re-run it
in one step. source("scripts/load-data.R") runs a whole script file, and everything it creates appears in your
session. In Positron, the Source ▷ button at the top of the editor does the same for the open file.
Exercises
Each exercise gives you up to 10 checked attempts. Use Run as many times as you like to experiment first, then click Check answer when you're ready. Your exercises use numbers/subsets unique to you, so answers won't match a classmate's exactly.
Exercise 1 — Build a data frame, row by row
0 / 10 attempts usedCreate a data frame trip_log for a trip (real or imaginary) with three columns: city
(text), country (text) and nights (a number). Start it with one row using
data.frame(), then use rbind() to add two more stops. Finally, add a logical
column rained (TRUE/FALSE, one per stop) with cbind().
Exercise 2 — Look beyond the top
0 / 10 attempts usedgm is loaded. Click Run to see your k. Store the last k rows of
gm in bottom, and 5 randomly chosen rows (no row twice) in spot_check.
Exercise 3 — Source a script
0 / 10 attempts usedThis exercise's pretend project has a data file and a script, scripts/load_region.R, that reads it.
Look at the script with readLines("scripts/load_region.R"). Then run the whole script with
source(), and store the number of rows of the data frame it creates in n_rows.
Exercise 4 — Read str() like a pro
0 / 10 attempts usedClick Run to print str(gm_sub), a random piece of gm that differs for every
student. Using only that output (no other functions!), fill in:
n_obs: how many rows;n_vars: how many columns;n_countries: how many levels thecountryfactor has;year_type: the typestr()shows foryear, exactly as printed (e.g."chr").
Key Points
str()tells you the size, the column types and the first values in one go.- Check the bottom and a random sample of rows, not just
head(). cbind()adds columns andrbind()adds rows; the pieces must match.source()re-runs a saved script so your data can always be rebuilt.
Proof of completion
Once you've attempted every exercise above, download a PDF summary of your work on this lesson — your name, the exercises you passed, attempt counts, timing, and your final code for each.