Data In The Wild
  1. Module 2
  2. 2.5: Module 2 Wrap-Up
  • Home
  • Contact Us
  • For Instructors

  • Module 1
    • Overview
    • 1.1: Introduction to R and RStudio
    • 1.2: Intro to Coding in R
    • 1.3: Introduction to the tidyverse
    • Assignment 2
    • Assignment 3
  • Module 2
    • Overview
    • 2.1: Good Food Gone Bad
    • 2.2: Plotting with ggplot2
    • 2.3: Data Visualization
    • 2.4: Exploring geom Functions
    • 2.5: Module 2 Wrap-Up
    • Assignment 1
    • Assignment 2
    • Assignment 3
  • Module 3
    • Overview
    • 3.1: Leopard Seals
    • 3.2: T-Tests
    • 3.3: Comparing (Multiple) Means
    • Assignment 1
    • Assignment 2
  • Module 4
    • Overview
    • 4.1: Combining Datasets (Joins & Binds)
    • 4.2: K-Nearest Neighbor
    • 4.3: Roads and Regressions
    • 4.4: Multiple Regression
    • 4.5: Writing Functions
    • Assignment 1
    • Assignment 2
    • Assignment 3
    • Assignment 4
  • Module 5
    • Overview
    • 5.1: Population Growth
    • 5.2: Sustainable Fishing
    • 5.3: Comparing Populations
    • Assignment 1
    • Assignment 2
    • Assignment 3
  • Final Project

  • Resources

On this page

  • What is causing the food poisoning?
    • Learning Outcomes
    • Set-up
      • Packages
      • Data
    • Which Fish?
      • Density
    • What Environmental Factor?
  1. Module 2
  2. 2.5: Module 2 Wrap-Up

2.5: Module 2 Wrap-Up

Author

Ellen Bledsoe, Lily McMullen

What is causing the food poisoning?

Learning Outcomes

  • Students will be able to apply descriptive statistics and data visualization skills to investigate a problem.
  • Students will be able to create a new variable using mutate().
  • Students will be able to use group_by() and summarize() to compare groups.
  • Students will be able to select and interpret appropriate plot types to identify patterns across environmental variables.

At the beginning of Module 2, we set out to discover what was causing food poisoning among our colleagues at our Antarctic base. Let’s put everything we’ve learned about descriptive statistics and data visualization to use to try to hunt down what the problem is.

Set-up

Let’s load the package and data we will need.

Packages

library(tidyverse)

Data

First, we need our dataset!

sick_fish <- read_csv("data/fish_sick_data.csv") 

Let’s check out our data and remind ourselves what we are working with.

head(sick_fish)
# A tibble: 6 × 7
  tank_id species avg_daily_temp num_fish day_length tank_volume num_sick
    <dbl> <chr>            <dbl>    <dbl>      <dbl>       <dbl>    <dbl>
1     388 tilapia           24.3       93         10        399.        3
2     425 tilapia           24.6       98         11        400.        4
3     420 tilapia           23.0      103          9        399.        2
4     819 trout             14.1       85         11        401.       14
5     176 tilapia           23.3       98         10        400.        3
6     926 trout             13.8       79         12        400.       10

Which Fish?

In the previous lesson, we plotted the number of sick fish. Let’s remind ourselves what that looked like. Make a plot that compares the numbers of sick fish per species. We actually have a few options!

# Write your code here

Answer:

ggplot(sick_fish, aes(num_sick, fill = species)) +
  geom_histogram(alpha = 0.5, position = "identity", bins = 10) +
  labs(x = "Number of Sick Fish in Tanks",
       y = "Frequency",
       fill = "Species") +
  theme_classic()

Density

Wait a second! Take a look back at the data. There is a “number of fish” column, indicating the total number of fish in the tank, and it looks like those numbers can differ pretty widely.

We should probably take into account how many fish there are in the tank to begin with. 12 sick fish out of 50 is probably a bigger deal than 12 sick fish out of 100!

What we need to do is calculate a density: the number of sick fish divided by the total number of fish in the tank.

# take into account the number of fish in the tank: density of sick fish
sick_fish <- sick_fish %>% 
  mutate(density = num_sick/num_fish) 

Small Groups

Let’s make sure our conclusions about trout being the true culprits still hold when we account for the total number of fish in the tank.

Work in small groups to do the following:

  • find the average number and standard deviation of sick fish for both species
  • make a plot that compares the distributions of sick fish numbers for both species (you have multiple options here!)
# Write your code here

Answer:

sick_fish %>% 
  group_by(species) %>% 
  summarize(mean_sick_fish = mean(density),
            sd_sick_fish = sd(density))
# A tibble: 2 × 3
  species mean_sick_fish sd_sick_fish
  <chr>            <dbl>        <dbl>
1 tilapia         0.0336       0.0207
2 trout           0.193        0.0327
# boxplot option
ggplot(sick_fish, aes(species, density, color = species)) +
  geom_boxplot() + 
  geom_jitter(alpha = 0.5, width = 0.1) +
  labs(x = "Species",
       y = "Density of Sick Fish in Tanks",
       color = "Species") +
  theme_light()

# histogram option
ggplot(sick_fish, aes(density, fill = species)) +
  geom_histogram(alpha = 0.5, bins = 15)

Instructor Note: Trout have a mean sick fish density of 0.193, roughly 5.7× higher than tilapia (0.034). The boxplot makes this immediately visible.

Uh oh… the trout densities look even worse than just the number of sick fish.

We should create a data frame that only contains trout to work with for the rest of our analyses. Take a few minutes to work on that; call it sick_trout.

# Write your code here

Answer:

sick_trout <- sick_fish %>% 
  filter(species == "trout")
sick_trout
# A tibble: 19 × 8
   tank_id species avg_daily_temp num_fish day_length tank_volume num_sick
     <dbl> <chr>            <dbl>    <dbl>      <dbl>       <dbl>    <dbl>
 1     819 trout             14.1       85         11        401.       14
 2     926 trout             13.8       79         12        400.       10
 3     851 trout             15.7       79         12        401.       17
 4     996 trout             15.7       86         13        400.       19
 5     776 trout             15.2       69         11        400.       13
 6     766 trout             15.1       79         12        400.       13
 7     964 trout             14.9       74         11        400.       12
 8     892 trout             15.1       87         13        400.       19
 9     793 trout             14.7       82         11        400.       16
10     751 trout             14.8       75         11        400.       20
11     945 trout             14.7       66         14        398.       12
12     944 trout             15.2       62         12        400.       15
13     844 trout             15.3       77         13        400.       16
14     973 trout             15.7       94         12        400.       16
15     920 trout             14.3       63         12        399.       13
16     980 trout             13.9       79         11        400.       14
17     816 trout             14.5       71         12        400.       15
18     783 trout             14.8       73         13        402.       12
19     909 trout             14.3       76         13        401.       14
# ℹ 1 more variable: density <dbl>

What Environmental Factor?

Take a look back at the data frame. Which columns are environmental variables that could be driving the issues?

Are those columns numeric or categorical? What plot type have we talked about that might help us find a relationship between density and each of these variables (one at a time…)?

Instructor Note: The environmental columns in the trout data are avg_daily_temp, num_fish, day_length, and tank_volume.

All are numeric, so scatter plots with density on the y-axis are the right choice.

In small groups, make plots using the density column in the sick_trout data to try to figure out which environmental factor is causing problems in the trout. Make one plot per variable so you can look at each relationship on its own.

# Write your code here

Answer:

ggplot(sick_trout, aes(x = avg_daily_temp, y = density)) +
  geom_point() +
  labs(x = "Average Daily Temperature (°C)", y = "Density of Sick Fish") +
  theme_light()

ggplot(sick_trout, aes(x = num_fish, y = density)) +
  geom_point() +
  labs(x = "Number of Fish in Tank", y = "Density of Sick Fish") +
  theme_light()

ggplot(sick_trout, aes(x = day_length, y = density)) +
  geom_point() +
  labs(x = "Day Length (hours)", y = "Density of Sick Fish") +
  theme_light()

ggplot(sick_trout, aes(x = tank_volume, y = density)) +
  geom_point() +
  labs(x = "Tank Volume", y = "Density of Sick Fish") +
  theme_light()

What do we think is the environmental driver causing issues with the trout?

Instructor Note: This is a discussion question, so keep it open and let students reason from their plots. Use the points below to guide the conversation rather than handing over the answer.

avg_daily_temp shows a positive relationship between temperature and sick fish density. As temperature goes up, density tends to go up. This makes biological sense, since rainbow trout are cold-water fish and even modest warming toward the upper end of their tolerance range stresses their immune function.

num_fish shows a slight negative trend: as the number of fish in a tank goes up, density drops a little. This is most likely a dilution effect in the density calculation (more total fish in the denominator) rather than a real biological pattern, and the scatter is wide.

day_length shows essentially no relationship

tank_volume is nearly constant across the trout tanks (everything sits right around 400). There is no variation to drive anything, which means we can rule it out as a cause.

Temperature is the primary driver.

Students haven’t learned how to fit a trend line yet, but if you want to make the pattern more obvious you can add geom_smooth(method = "lm") to the temperature plot as a preview of the regression work coming in Module 3. Close by asking what they would recommend to the Antarctic base team, which sets up that transition.

2026, University of Arizona & Lewis & Clark College

 
  • Made with Quarto