Practice Session & Exercise

Introduction to R and Basic Programming Concepts

Author
Affiliation

Bioinformatics Core Facility CECAD

Published

September 24, 2026

1 Intermediate R-Course 2026

2 Session 3 Practice: ggplot2

This one-hour practice session follows the slides and the Kahoot quiz. Try each task before you open the solution. The exercises use iris, the built-in plant-physiology dataset CO2, and ggplot2.

Not everyone works through exercises at the same pace, so each one below is flagged — but the exercises build on each other, so everyone still works through them in order, together as a group. The flags aren’t an invitation to skip ahead; they tell you what to expect, and what to do if you’re falling behind:

  • 🟢 Easy — everyone should get through these by writing the code themselves.
  • 🟡 Medium — a bit harder, or an optional add-on; keep typing if you’re keeping pace, but copying from the solution is fine too.
  • 🔴 Challenge — the most demanding exercises, including today’s only new programming idea (writing your own function). If you’re falling behind, copy the code from the solution instead of typing it yourself, then move on together with the group.

2.1 Session 3

2.1.1 Exercise 1: Fixed versus mapped colour 🟢 Core

Start with this scatter plot:

p <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_point()
print(p)

Create two named versions:

  • p_grouped: map Species to colour so a legend appears.
  • p_fixed: make every point one fixed blue colour.

Print both versions. Which one has a legend, and why?

2.1.2 Exercise 2: Extend a plot object without overwriting it 🟢 Core

Using p_grouped from Exercise 1, create three named versions:

  • p_trend: add one linear trend per species with geom_smooth(method = "lm", se = FALSE).
  • p_panels: split the plot into species panels with facet_wrap(~ Species).
  • p_report: start from p_panels, then add labels and theme_classic().

Print p_report and then print p_grouped. Is the original still unchanged?

2.1.3 Exercise 3: Put plot objects in lists and functions 🔴 Challenge

Keep the versions from Exercise 2 in a list called plots, with elements named grouped, trend, panels, and report.

Then write render_plot(plot, file) using ggsave(). Use it to save the report version as iris_report.png.

2.1.4 Exercise 4: Choose the geom and add observations 🟡 Stretch

Using iris, make three complementary plots:

  1. A count of flowers in each species with geom_bar().
  2. A histogram of Petal.Length. Compare binwidth = 0.5 and binwidth = 1.
  3. A boxplot of Petal.Length by species with jittered observations.

Optional: create a count table with dplyr::count() and reproduce the first plot with geom_col(). What changes when the y values are supplied?

2.1.5 Exercise 5: Capstone figure and reproducible outputs 🔴 Challenge

iris only gives one grouping variable (Species), so for a figure that needs two we switch to another built-in biological dataset: CO2, CO2 uptake rates in chilled and non-chilled grass plants from Quebec and Mississippi (see ?CO2).

Build one figure in named stages. The final plot should:

  • put conc (ambient CO2 concentration) on x and uptake on y;
  • colour points by Type (Quebec vs. Mississippi);
  • add one linear trend per Type;
  • split into panels by Treatment (chilled vs. nonchilled);
  • include readable labels, a title, and a clean theme.

Keep p_points, p_fits, and p_final as separate objects. Print all three and describe what each added layer contributes.

Finally:

  • save p_final as co2_summary.png at 300 dpi;
  • save the plot object as co2_plot.rds;
  • restore it with readRDS() and add a presentation theme.

2.2 Exit ticket

  1. What belongs inside aes(), and what belongs outside it?
  2. Which object is your reusable starting point?
  3. What is the difference between the PNG and the RDS file?

Sources: ggplot2 reference, ggplot2 book, and ggsave() documentation.