MC³ LabCUHK Psychology

Lesson 8 · Working with data

Charts: one variable

Build your first charts with ggplot2, a layer at a time.

In this lesson

  • The ggplot recipe
  • Histograms for numbers
  • Bar charts for categories

You need

Datastudents.csvStudent Life Survey: 300 students, with their study habits, sleep, stress, wellbeing and exam results.
Scriptlesson-08.RAll the code in this lesson, ready to run.

Set up

R code
library(tidyverse)
students <- read_csv("data/students.csv", show_col_types = FALSE) %>%
  mutate(Motivation = factor(Motivation, levels = c("Low", "Medium", "High")))

The recipe

1. Data

ggplot(students,

+
2. Aesthetics

which column goes where
aes(x = ExamScore))

+
3. Geom

what to draw
geom_histogram()

Every ggplot chart is built from these three parts, joined with +.

Data and aesthetics alone give an empty canvas:

R code
ggplot(students, aes(x = ExamScore))
An empty chart with exam score on the x axis

Add a geom with +:

R code
ggplot(students, aes(x = ExamScore)) +
  geom_histogram()
Output
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.
Histogram of exam scores in 30 narrow bars

The message suggests choosing a bar width. Let's do that.

Histograms: one number

A histogram shows how values are spread: where most are, and how wide the spread is.

R code
ggplot(students, aes(x = ExamScore)) +
  geom_histogram(binwidth = 5, fill = "steelblue", colour = "white")
Histogram of exam scores in 5-mark bars; most students scored between 55 and 80
  • binwidth = 5: each bar covers 5 marks.
  • fill colours the bars, colour their outline.

Colour by group

Put fill inside aes() to colour by a column. facet_wrap() gives each group its own panel:

R code
ggplot(students, aes(x = ExamScore, fill = Gender)) +
  geom_histogram(binwidth = 5, colour = "white") +
  facet_wrap(~ Gender)
Two histograms of exam scores, for female and male students, with similar shapes
Outside aes()

fill = "steelblue"
sets one colour for all

Inside aes()

aes(fill = Gender)
colours by a column, adds a legend

Bar charts: categories

geom_bar() counts rows in each category:

R code
ggplot(students, aes(x = Motivation)) +
  geom_bar()
Bar chart of the number of students in each motivation group; Medium is the largest

Split each bar by another category with fill, side by side with position = "dodge":

R code
ggplot(students, aes(x = Motivation, fill = Gender)) +
  geom_bar(position = "dodge")
Grouped bar chart of motivation for female and male students

Exercises

Exercise 8.1 Dataset: students.csv

Histogram of sleep

Make a histogram of Sleep with bars half an hour wide (binwidth = 0.5). What does the warning mean?

Show answerHide answer
R code
ggplot(students, aes(x = Sleep)) +
  geom_histogram(binwidth = 0.5, fill = "darkseagreen", colour = "white")
Output
Warning message:
Removed 10 rows containing non-finite outside the scale range
(`stat_bin()`).
Histogram of hours of sleep; most students sleep between 5.5 and 7.5 hours

Most students sleep 5.5 to 7.5 hours. The warning says 10 rows were left out: the students with no sleep answer.

Exercise 8.2 Dataset: students.csv

Bar chart

Make a bar chart of Living (Hall or Home), split by Workshop, side by side.

Show answerHide answer
R code
ggplot(students, aes(x = Living, fill = Workshop)) +
  geom_bar(position = "dodge")
Grouped bar chart of where students live, split by whether they took the workshop

Key points

  • ggplot(data, aes(...)) + geom_...()
  • Histogram = one number; bar chart = counts of categories.
  • Inside aes() maps a column; outside sets a fixed look.