Day 3 - Wednesday, May 20, 2026
Today: Wednesday May 20
Before class
Plan for today
Helpful links
Yesterday we covered:
<-Today we’ll build on that to start reading and writing real R code.
Yesterday’s textbook reading made one key point:
Before you can write R code, you need to be able to read it.
Most people who write code start by copying and modifying existing code.
To do that well, you need to recognize a few key patterns and know what each piece of an expression is doing.
When you look at a line of R code, you’ll mostly see these five things:
BabyNames)filter(), mean())name, sex)"Arjun" or 1998Note
The capital/lowercase convention is a style choice that is followed by the Data Computing textbook; but it is not strictly enforced by R.
Try to identify:
This single command counts the total number of babies named “Arjun” in the data: 5,578.
Try to identify:
BabyNames (starts with capital, no parentheses after it)filter, summarise, sum (each followed by an open parenthesis)name, count (lowercase, inside parentheses)"Arjun" (in quotes)total = sum(count) (single = inside the function call)This single command counts the total number of babies named “Arjun” in the data: 5,578.
An object is anything in R that has a name you can refer to later.
Once an object exists, you can use its name anywhere you’d otherwise type the value:
Compare:
vs.
Good names make your code readable and easy to change later.
| Object type | Convention | Example |
|---|---|---|
| Data tables | Capitalized | BabyNames, Penguins |
| Variables / columns | lowercase | name, body_mass_g |
| Constants you create | lowercase, snake_case | age_cutoff, gpa_min |
Warning
Object names must start with a letter and can only contain letters, numbers, _, and .. No spaces, no special characters, no starting with a number. This is a requirement, not a convention.
A function is a reusable chunk of code that takes some input, does something with it, and gives you back an output.
You’ve already used many functions:
Every function call has the same three key elements: a name, followed by parentheses, with arguments inside.
name = value); others are matched by position.[1] 1 3 5 7 9
[1] 1 3 5 7 9
A good habit
Your future self will thank you when reading the code six weeks from now.
If you don’t remember what arguments a function takes:
Every help page has the same sections: Description, Usage, Arguments, Value, Examples.
Every function gives you back a value. You can store that value with <-:
If you don’t assign the result, R just prints it to the console and it’s gone. The result will not be stored anywhere for you to access in the future.
The output of one function can become the input to another:
R works inside-out:
c(1, 4, 9, 16, 25) makes a vector.mean(...) of that vector is 11.sqrt(11) is ≈ 3.317.This nesting can get unreadable fast. Later on, we’ll see a cleaner way (the pipe).
Base R has a lot of features, but many useful tools live in packages.
A package is a bundle of:
Packages are written by someone in the R community and made available for everyone to use.
There are over 23,000 packages on CRAN (the main R package repository).
There are two steps to using a package.
Install once, load every session
install.packages("packagename") - do this once per computer.library(packagename) - do this every time you start a new R session.Quotation marks matter: install.packages("tidyverse") (string), but library(tidyverse) (object).
Run install.packages() in the Console, not in your script.
You only need to install once, so it doesn’t belong in a script that runs every time.
If your script needs a package, just put library(packagename) at the top.
── Attaching core tidyverse packages ──────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.4 ✔ tidyr 1.3.1
✔ purrr 1.0.4
── Conflicts ────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
These messages are fine. They mean: “Here are the packages I just loaded, and here are the function names that now point to a new place.”
The tidyverse is a collection of R packages that share a common philosophy and work well together.
When you run library(tidyverse), you load all of them at once:
ggplot2 - making plotsdplyr - manipulating data tablestidyr - reshaping datareadr - reading data filestibble - a nicer kind of data framestringr - working with textforcats - working with categorical datapurrr - applying functions across collectionsWe will use almost all of them this semester.
Each tidyverse package has its own hex sticker - a fun tradition in the R community.
Two reasons:
We’ll spend most of the semester learning to think in this style.
Don’t worry about understanding every line - just notice how readable this is:
# A tibble: 3 × 3
species n avg_mass_g
<fct> <int> <dbl>
1 Adelie 151 3701.
2 Chinstrap 68 3733.
3 Gentoo 123 5076.
This is the dplyr package in action. We’ll cover it in detail later this week.
ggplot2 (part of the tidyverse) is the most popular plotting package in R.
It’s built on the idea of a grammar: you build up a plot by adding layers.
Every ggplot2 plot has at least three pieces:
aes(...)) - which variables map to which parts of the plot (x, y, color, fill, etc.).geom_*()) - what kind of plot (points, bars, lines, histograms…).A histogram shows the distribution of a single numeric variable by bucketing values into bins and counting how many fall in each bin.
It’s the right tool when you want to ask:
In ggplot2, you make a histogram with geom_histogram().
Breaking it down:
ggplot(penguins, ...): start a plot using the penguins data.aes(x = body_mass_g): map the variable body_mass_g to the x-axis.+ geom_histogram(): add a histogram layer.Note
In ggplot2, you add layers with +, not with %>% or |>.
R will warn you: “stat_bin() using bins = 30. Pick better value with binwidth.”
You can control the number of bins two ways:
Too few bins
You lose detail and the shape gets oversmoothed.
You see noise and the shape gets jagged and hard to read.
There’s no single “right” answer. Try a few, and pick what tells the clearest story about your data.
Add fill, color, and labels:
| Piece | What it does |
|---|---|
ggplot(penguins, aes(x = body_mass_g)) |
Use the penguins data; put body_mass_g on x |
geom_histogram(...) |
Add the histogram layer |
binwidth = 250 |
Each bar is 250 g wide |
fill = "steelblue" |
Bar color |
color = "white" |
Outline color |
labs(...) |
Title and axis labels |
Tip
You can run ?geom_histogram in the Console to see every option.
You’ll work on this individually or with a neighbor for 20 minutes. We’ll regroup at the end.
Goal: Make a histogram of a real dataset and tweak it.
Setup:
day3-activity.R starter file from Canvas.File > Open File... and open the script you downloaded.Step 1 - Load packages
At the top of your script, type and run:
If palmerpenguins isn’t installed, run install.packages("palmerpenguins") in the Console first.
Step 2 - Look at the data
What variables are in this data set? What does each row represent?
Step 3 - Make a default histogram
Pick a numeric variable from penguins (e.g., flipper_length_mm, bill_length_mm, bill_depth_mm).
Step 4 - Tweak your histogram
Make at least three changes to your histogram:
binwidth or bins value.fill and color of the bars.labs(...).Step 5 - Comment
Open a comment block in your script and write 2–3 sentences answering:
To turn in:
Save your script (Cmd/Ctrl + S). Upload the .R file to the Canvas assignment page.
Stuck?
+, or unmatched (.Some things to look out for:
+ between layers: R thinks the line is finished.= instead of <-: works in some places, but breaks elsewhere.Error: could not find function "ggplot": run library(tidyverse).ggplot2 from scratch.Tomorrow: Quarto basics, writing reproducible documents.
Upcoming Deadlines