wk6-d01-multi-df
Chico State
DATA 385 - Fall 2026
September 29, 2026
🎥wk6-d01 multiple df
So far we’ve worked with a single data frame and transformed it with dplyr functions. Now we have multiple data frames, and we want to bring them together.
| name |
|---|
| Ada Lovelace |
| Marie Curie |
| Janaki Ammal |
| Chien-Shiung Wu |
| Katherine Johnson |
| Rosalind Franklin |
| Vera Rubin |
| Gladys West |
| Flossie Wong-Staal |
| Jennifer Doudna |
The information on these 10 scientists has been spread across three data frames on purpose. Not every data frame has information on every scientist, which is a lot closer to real life than having complete data on everyone.
Source: Discover Magazine
professions# A tibble: 10 × 2
name profession
<chr> <chr>
1 Ada Lovelace Mathematician
2 Marie Curie Physicist and Chemist
3 Janaki Ammal Botanist
4 Chien-Shiung Wu Physicist
5 Katherine Johnson Mathematician
6 Rosalind Franklin Chemist
7 Vera Rubin Astronomer
8 Gladys West Mathematician
9 Flossie Wong-Staal Virologist and Molecular Biologist
10 Jennifer Doudna Biochemist
We know the profession of all 10 scientists. e.g. Ada Lovelace was a mathematician, Marie Curie a physicist and chemist. This is the only complete data frame.
dates# A tibble: 8 × 3
name birth_year death_year
<chr> <dbl> <dbl>
1 Janaki Ammal 1897 1984
2 Chien-Shiung Wu 1912 1997
3 Katherine Johnson 1918 2020
4 Rosalind Franklin 1920 1958
5 Vera Rubin 1928 2016
6 Gladys West 1930 NA
7 Flossie Wong-Staal 1947 NA
8 Jennifer Doudna 1964 NA
We have birth and death years for 8 of the 10 scientists. An NA for death_year doesn’t mean unknown, but that she is still living.
works# A tibble: 9 × 2
name known_for
<chr> <chr>
1 Ada Lovelace first computer algorithm
2 Marie Curie theory of radioactivity, discovery of elements …
3 Janaki Ammal hybrid species, biodiversity protection
4 Chien-Shiung Wu confim and refine theory of radioactive beta dec…
5 Katherine Johnson calculations of orbital mechanics critical to se…
6 Vera Rubin existence of dark matter
7 Gladys West mathematical modeling of the shape of the Earth …
8 Flossie Wong-Staal first scientist to clone HIV and create a map of…
9 Jennifer Doudna one of the primary developers of CRISPR, a groun…
For 9 of the 10 scientists we have information on what they’re known for e.g. Ada Lovelace for the first computer algorithm, Marie Curie for the theory of radioactivity.
# A tibble: 10 × 5
name profession birth_year death_year known_for
<chr> <chr> <dbl> <dbl> <chr>
1 Ada Lovelace Mathematician NA NA first co…
2 Marie Curie Physicist and C… NA NA theory o…
3 Janaki Ammal Botanist 1897 1984 hybrid s…
4 Chien-Shiung Wu Physicist 1912 1997 confim a…
5 Katherine Johnson Mathematician 1918 2020 calculat…
6 Rosalind Franklin Chemist 1920 1958 <NA>
7 Vera Rubin Astronomer 1928 2016 existenc…
8 Gladys West Mathematician 1930 NA mathemat…
9 Flossie Wong-Staal Virologist and … 1947 NA first sc…
10 Jennifer Doudna Biochemist 1964 NA one of t…
One row per scientist (10 rows) and 5 columns: name, profession from the first data frame, birth_year and death_year from the second, and known_for from the third.
All three share one variable, name, and that’s what gets used as the linking variable by default. We know they don’t all have the same number of rows, but we don’t yet know which scientists are missing from which data frame.
left_join(): all rows from xright_join(): all rows from yfull_join(): all rows from both x and ysemi_join(): all rows from x where there are matching values in y, keeping just columns from xinner_join(): all rows from x where there are matching values in y, return all combination of multiple matches in the case of multiple matchesanti_join(): return all rows from x where there are not matching values in y, never duplicate rows of xx and yFor the next few slides…
Some ids are in both data frames (1 and 2) and some are in only one (3 and 4), so it’s easy to see what each join keeps.
left_join()
Keep all the rows of x (the left one), and bring along the information from y wherever it exists. id = 4 exists in y but not in x, so it disappears.
left_join()# A tibble: 10 × 4
name profession birth_year death_year
<chr> <chr> <dbl> <dbl>
1 Ada Lovelace Mathematician NA NA
2 Marie Curie Physicist and Chemist NA NA
3 Janaki Ammal Botanist 1897 1984
4 Chien-Shiung Wu Physicist 1912 1997
5 Katherine Johnson Mathematician 1918 2020
6 Rosalind Franklin Chemist 1920 1958
7 Vera Rubin Astronomer 1928 2016
8 Gladys West Mathematician 1930 NA
9 Flossie Wong-Staal Virologist and Molecular … 1947 NA
10 Jennifer Doudna Biochemist 1964 NA
We keep all the information from professions and bring in birth_year and death_year. Ada Lovelace and Marie Curie are missing from dates, so they get NA birth and death years. we don’t lose their rows, because they exist in professions.
right_join()
The same thing the other way around: keep all the rows of y, and id 3 goes away.
❓Why not just swap the order in a left_join()?
right_join()# A tibble: 8 × 4
name profession birth_year death_year
<chr> <chr> <dbl> <dbl>
1 Janaki Ammal Botanist 1897 1984
2 Chien-Shiung Wu Physicist 1912 1997
3 Katherine Johnson Mathematician 1918 2020
4 Rosalind Franklin Chemist 1920 1958
5 Vera Rubin Astronomer 1928 2016
6 Gladys West Mathematician 1930 NA
7 Flossie Wong-Staal Virologist and Molecular B… 1947 NA
8 Jennifer Doudna Biochemist 1964 NA
This time we lose Ada Lovelace and Marie Curie, since they aren’t in dates. Everyone else gets their profession from professions.
full_join()
Keep all the rows from both, and wherever information is missing we end up with NAs.
full_join()# A tibble: 10 × 4
name birth_year death_year known_for
<chr> <dbl> <dbl> <chr>
1 Janaki Ammal 1897 1984 hybrid species, biodivers…
2 Chien-Shiung Wu 1912 1997 confim and refine theory …
3 Katherine Johnson 1918 2020 calculations of orbital m…
4 Rosalind Franklin 1920 1958 <NA>
5 Vera Rubin 1928 2016 existence of dark matter
6 Gladys West 1930 NA mathematical modeling of …
7 Flossie Wong-Staal 1947 NA first scientist to clone …
8 Jennifer Doudna 1964 NA one of the primary develo…
9 Ada Lovelace NA NA first computer algorithm
10 Marie Curie NA NA theory of radioactivity, …
dates has 8 scientists and works has 9, but not the same ones. We get dates for the 8, and known_for for Ada Lovelace and Marie Curie from works. Rosalind Franklin is missing from works, so her known_for is NA. We end up with all 10 rows because we had at least one piece of information about all 10 women.
inner_join()An intersection: only give me the rows for which I have data in both data frames.
inner_join()# A tibble: 7 × 4
name birth_year death_year known_for
<chr> <dbl> <dbl> <chr>
1 Janaki Ammal 1897 1984 hybrid species, biodiversi…
2 Chien-Shiung Wu 1912 1997 confim and refine theory o…
3 Katherine Johnson 1918 2020 calculations of orbital me…
4 Vera Rubin 1928 2016 existence of dark matter
5 Gladys West 1930 NA mathematical modeling of t…
6 Flossie Wong-Staal 1947 NA first scientist to clone H…
7 Jennifer Doudna 1964 NA one of the primary develop…
Only the 7 scientists that are in both dates and works.
semi_join()Very similar to an inner join, except the information in y is only used to decide which rows of x to keep. None of y’s columns come along.
semi_join()# A tibble: 7 × 3
name birth_year death_year
<chr> <dbl> <dbl>
1 Janaki Ammal 1897 1984
2 Chien-Shiung Wu 1912 1997
3 Katherine Johnson 1918 2020
4 Vera Rubin 1928 2016
5 Gladys West 1930 NA
6 Flossie Wong-Staal 1947 NA
7 Jennifer Doudna 1964 NA
The same 7 rows as the inner join, but there’s no known_for column. That column is gone.
anti_join()A subtraction: the rows in x that are not in y.
anti_join()# A tibble: 1 × 3
name birth_year death_year
<chr> <dbl> <dbl>
1 Rosalind Franklin 1920 1958
The one scientist we have birth and death years for, but no information on what she’s known for: Rosalind Franklin.
# A tibble: 10 × 5
name profession birth_year death_year known_for
<chr> <chr> <dbl> <dbl> <chr>
1 Ada Lovelace Mathematician NA NA first co…
2 Marie Curie Physicist and C… NA NA theory o…
3 Janaki Ammal Botanist 1897 1984 hybrid s…
4 Chien-Shiung Wu Physicist 1912 1997 confim a…
5 Katherine Johnson Mathematician 1918 2020 calculat…
6 Rosalind Franklin Chemist 1920 1958 <NA>
7 Vera Rubin Astronomer 1928 2016 existenc…
8 Gladys West Mathematician 1930 NA mathemat…
9 Flossie Wong-Staal Virologist and … 1947 NA first sc…
10 Jennifer Doudna Biochemist 1964 NA one of t…
Start with professions because it has all 10 rows. Left join dates to get birth and death years for whoever we have them for (still 10 rows), then left join works to get known_for.
We never had to say “match by name” because it’s the only column the three have in common. It had to be spelled exactly the same way in all of them for this to work.
# A tibble: 3 × 4
id name.x name.y username
<dbl> <chr> <chr> <chr>
1 1 Dave Friday <NA> <NA>
2 2 Hermine Hermine bakealongwithhermine
3 3 Sura Selvarajah Sura surasbakes
Start with enrolment, since the official records are the truth on any given day. Use the by argument, with the column name as a character string, to say “don’t try to match by name, just match by id.” Both data frames had a name column, so R keeps both and adds the suffixes .x (first data frame) and .y (second data frame).
In enrolment but not in survey. Chase these students down for their survey.
# A tibble: 2 × 3
id name username
<dbl> <chr> <chr>
1 4 Peter peter_bakes
2 5 Mark thebakingbuddha
Filled out the survey in the first days of class, but no longer on the enrollment records. Don’t need, dropped from further records (e.g. removed from the class GitHub organization).
Start with purchases and left join prices to see the price of each item purchased. Once the data are in a single data frame, the single data frame verbs work as usual: sum up the price column for a total revenue of £5.75.
All it takes is a group_by() right before the summarise().
In both case studies the data lived in separate data frames, and we had to bring them together first before we could get any further insight from them.
Note
This page adapts material from Data Science in a Box (Unit 2, Deck 8: “Working with multiple data frames”) by Mine Çetinkaya-Rundel, licensed under CC BY-SA 4.0. Source: tidyverse/datascience-box. Modified: converted from xaringan to Quarto revealjs; added talking points from the DSBox video.