library(ISLR)
library(tidyverse)Data visualization using ggplot2
Introduction
In this practical, we will learn how to create data visualisations using the grammar of graphics, implemented in R through the ggplot2 package (part of the tidyverse). We will build up the grammar step by step in Part 1, using baseball data from the ISLR package and a small simulated dataset of student grades. In Part 2, we put those pieces to work on a real research question: how are serving size, item type, and calorie content associated?
An excellent reference manual for ggplot can be found on the tidyverse website: https://ggplot2.tidyverse.org/reference/
Part 1: The grammar of graphics
What is ggplot?
Plots can be made in R without the use of ggplot using plot(), hist() or barplot() and related functions. Here is an example of each on the Hitters dataset from ISLR:
# Get an idea of what the Hitters dataset looks like
head(Hitters) AtBat Hits HmRun Runs RBI Walks Years CAtBat CHits CHmRun
-Andy Allanson 293 66 1 30 29 14 1 293 66 1
-Alan Ashby 315 81 7 24 38 39 14 3449 835 69
-Alvin Davis 479 130 18 66 72 76 3 1624 457 63
-Andre Dawson 496 141 20 65 78 37 11 5628 1575 225
-Andres Galarraga 321 87 10 39 42 30 2 396 101 12
-Alfredo Griffin 594 169 4 74 51 35 11 4408 1133 19
CRuns CRBI CWalks League Division PutOuts Assists Errors
-Andy Allanson 30 29 14 A E 446 33 20
-Alan Ashby 321 414 375 N W 632 43 10
-Alvin Davis 224 266 263 A W 880 82 14
-Andre Dawson 828 838 354 N E 200 11 3
-Andres Galarraga 48 46 33 N E 805 40 4
-Alfredo Griffin 501 336 194 A W 282 421 25
Salary NewLeague
-Andy Allanson NA A
-Alan Ashby 475.0 N
-Alvin Davis 480.0 A
-Andre Dawson 500.0 N
-Andres Galarraga 91.5 N
-Alfredo Griffin 750.0 A
# histogram of the distribution of salary
hist(Hitters$Salary, xlab = "Salary in thousands of dollars")# barplot of how many members in each league
barplot(table(Hitters$League))# Number of career hits versus number of career home runs
plot(x = Hitters$Hits, y = Hitters$HmRun,
xlab = "Hits", ylab = "Home runs")These plots are informative and useful for visually inspecting the dataset, and they each have a specific syntax associated with them. ggplot has a more unified approach to plotting, where you build up a plot layer by layer using the + operator:
homeruns_plot <-
ggplot(Hitters, aes(x = Hits, y = HmRun)) +
geom_point() +
labs(x = "Hits", y = "Home runs")
homeruns_plotAs introduced in the lecture, a ggplot object is built up in different layers:
- input the dataset to a
ggplot()function call - construct aesthetic mappings
- add (geometric) components to your plot that use these mappings
- add labels, themes, visuals.
Because of this layered syntax, it is then easy to add elements like these fancy density lines, a title, and a different theme:
homeruns_plot +
geom_density_2d() +
labs(title = "Cool density and scatter plot of baseball data") +
theme_minimal()Aesthetics and data preparation
The first step in constructing a ggplot is the preparation of your data and the mapping of variables to aesthetics. ggplot() always expects a data frame with correctly typed columns: numbers as numeric, categories as factor, identifiers as character.
Mapping aesthetics is usually done in the main ggplot() call, as the second argument after the data.
Geoms
The geoms in ggplot2 are added via geom_<geomtype>() functions, each with its own required aesthetic mapping (see ?geom_<geomtype>, or the reference website). Some geoms transform the data before plotting (e.g. geom_density_2d() calculates contour lines); others, like geom_point(), use the aesthetic mapping directly.
We now switch from the scatter plots above to distributional and comparative geoms, using the gg_students data.
Boxplot, Sina plot and bar plot
A common task is comparing distributions across groups. The boxplot (geom_boxplot()) does this through summary statistics; the bar plot (geom_bar()) compares counts of a categorical variable.
geom_bar() automatically transforms variables to counts (see ?stat_count), similar to how table() works.
We have now covered the core grammar: aesthetics, geoms, scales, and themes. In Part 2 we add one more piece, i.e., the facets, while applying everything to a real dataset.