2. Introduction section charts

Author

Sagar Shah, Rethink Priorities

Published

March 18, 2024

About this file

This file prepares the charts used in the introduction section of the report.

Prep

Clear memory, load packages and run functions script.

Code
rm(list=ls())
library(readxl)
library(tidyverse)
library(magrittr)
library(RColorBrewer)
library(scales)
library(gt)
source("a_functions.R")

Load and process data

I first input a spreadsheet from fishcount.org, providing estimates of the mean slaughter weight and mean lifespan of the 24 most commonly farmed finfish species.

Code
lifeexp <- 
  # Read file
  read_excel(
              "../1_input_data/fishcount_living.xlsx",
              range = "A9:V33") |>
  # Select collumns needed
          select(1,9:10,13:14) %>%
  # Convert collumn names to lower case
          mutate(across(1,str_to_lower))

# Rename collumns
names(lifeexp) <- c("species","weight_lower","weight_upper","lifespan_lower","lifespan_upper")

lifeexp
# A tibble: 24 × 5
   species               weight_lower weight_upper lifespan_lower lifespan_upper
   <chr>                        <dbl>        <dbl>          <dbl>          <dbl>
 1 grass carp(=white am…          500         2500             12             24
 2 silver carp                    300         1500             24             24
 3 common carp                    500         2500             10             48
 4 nile tilapia                   250          800              6              7
 5 bighead carp                   500         1500             14             28
 6 carassius spp                  150          400             12             19
 7 catla                          300         2000             14             21
 8 atlantic salmon               3614         8434             22             27
 9 roho labeo                     300         1500             14             21
10 pangas catfishes nei           500         1500             10             14
# ℹ 14 more rows

I then select the species I’m interested in (based on consumption in the EU).

Code
#Define search terms to filter collumns
species_list <- c("common carp","pangas","north african","trout",
                  "seabream","seabass","salmon","tilapia","striped") %>% 
                  paste(collapse="|")

# Filter collumns based on search terms
lifeexp %<>% filter(str_detect(species,species_list)) 

# Assign each species line to a species group
species_data<- lifeexp %>%
mutate(
  species_group=case_when(
    str_detect(species,"carp") ~ "Common Carp",
    str_detect(species,"salmon") ~ "Salmon",
    str_detect(species,"catfish") ~ "Freshwater Catfish",
    str_detect(species,"trout") ~ "Rainbow Trout",
    str_detect(species,"seabream") ~ "Gilthead Seabream",
    str_detect(species,"seabass") ~ "European Seabass",
    str_detect(species,"tilapia") ~ "Tilapia",
    TRUE ~ "ERROR"
  )
) %>%
  
# Order rows by species group
  relocate(species_group) %>%
  arrange(species_group) 
  
# Calculate upper/lower/average weights and lifespans across all species within a species group
species_data  %<>%
  group_by(species_group) %>%
  summarise(
    weight_lower=min(weight_lower),
    weight_upper=max(weight_upper),
    weight_av=(min(weight_lower)+max(weight_upper))/2,    
    lifespan_lower=min(lifespan_lower),
    lifespan_upper=max(lifespan_upper),
    lifespan_av=(min(lifespan_lower)+max(lifespan_upper))/2
  ) 

species_data
# A tibble: 7 × 7
  species_group      weight_lower weight_upper weight_av lifespan_lower
  <chr>                     <dbl>        <dbl>     <dbl>          <dbl>
1 Common Carp                 500         2500      1500             10
2 European Seabass            400          500       450             14
3 Freshwater Catfish          500         1500      1000             10
4 Gilthead Seabream           300          400       350             12
5 Rainbow Trout               210         5000      2605              9
6 Salmon                     3614         8434      6024             22
7 Tilapia                     250          800       525              6
# ℹ 2 more variables: lifespan_upper <dbl>, lifespan_av <dbl>

Modify weight and lifespan data

I then supplement the fishcount data with my own figures where I think I have better numbers in the EU context than those provided by fishcount.

  • (Small) Rainbow trout - Add in a median expected weight of 500g rather than the mid-point, given number of lives is likely to skew more heavily towards smaller weights given consumption is dominated by weight in countries consuming smaller trout. Used longer life expectancy based on Jokumsen & Svendsen (2010), Animal Ask Denmark report, and EUMOFA case study.

  • (Large) Rainbow Trout - Used longer life expectancy based on Animal Ask Denmark report and EUMOFA case study, and various websites suggesting around 1.5 years during on-growing phase to achieve harvest weight.

  • Atlantic Salmon - Used mean weight from Norwegian Fish Health report average slaughter weight and number of smolts put out to sea. Used life expectancy based on Mowi Industry report.

  • Carp - Used data from EUMOFA report suggesting typical weights for consumption is 1.5 to 2kg, and typically 3 year production cycle. Small carp seem less commonly consumed in EU.

Code
species_data %<>%
  rbind(
   c("Rainbow Trout (small)",210,1200,500,12,15,13.5),
  c("Rainbow Trout (large)",1200,5000,3100,21,26,23.5),
  c("Atlantic Salmon",3614,8434,5663,22,40,31),
  c("Carp",1250,2250,1750,30,42,36)
  ) %>%
    mutate(across(2:7,as.double))

species_data
# A tibble: 11 × 7
   species_group         weight_lower weight_upper weight_av lifespan_lower
   <chr>                        <dbl>        <dbl>     <dbl>          <dbl>
 1 Common Carp                    500         2500      1500             10
 2 European Seabass               400          500       450             14
 3 Freshwater Catfish             500         1500      1000             10
 4 Gilthead Seabream              300          400       350             12
 5 Rainbow Trout                  210         5000      2605              9
 6 Salmon                        3614         8434      6024             22
 7 Tilapia                        250          800       525              6
 8 Rainbow Trout (small)          210         1200       500             12
 9 Rainbow Trout (large)         1200         5000      3100             21
10 Atlantic Salmon               3614         8434      5663             22
11 Carp                          1250         2250      1750             30
# ℹ 2 more variables: lifespan_upper <dbl>, lifespan_av <dbl>

I now input data on apparent consumption of the most consumed farmed finfish species in the EU27 in 2021, taken from supply balance sheet data from EUMOFA.

Splits between large and small rainbow trout are based on the EUMOFA large trout case study.

Code
eu_consumption_2021 <- tibble(
# Define species names
  species_group=c('Atlantic Salmon',"Rainbow Trout",'Rainbow Trout (large)',"Rainbow Trout (small)",'Gilthead Seabream','European Seabass','Freshwater Catfish','Carp','Tilapia'),
# Add consupmtion in metric tonnes
  consumption=c(1097029,216425,94033,122392,136724,106776,102039,79726,39833)) %>%
# Convert to grammes (as fish weight reported in grammes)
  mutate(consumption=consumption*1E6)

eu_consumption_2021
# A tibble: 9 × 2
  species_group           consumption
  <chr>                         <dbl>
1 Atlantic Salmon       1097029000000
2 Rainbow Trout          216425000000
3 Rainbow Trout (large)   94033000000
4 Rainbow Trout (small)  122392000000
5 Gilthead Seabream      136724000000
6 European Seabass       106776000000
7 Freshwater Catfish     102039000000
8 Carp                    79726000000
9 Tilapia                 39833000000

Run calculations

I then add in the data with species specific data and work out number of animals slaughtered and age.

Note that my uncertainty ranges for lifespan will probably be too narrow, as I’ve assumed perfect correlation between slaughter weight and lifespan ranges (i.e. heaviest fish have longest lifespan, while lightest fish will have longest lifespan). Had I allowed for the opposite (lightest fish to be associated with longest lifespan), the ranges would have probably have been too wide.

Code
eu_consumption_2021 %<>%
# Add fish weight and lifespan data
  left_join(species_data,by="species_group") %>%
  rowwise() %>%
  mutate(
# Number of fish slaughtered figures
    slaughter_upper=consumption/weight_lower,
    slaughter_lower=consumption/weight_upper,
    slaughter_midweight=consumption/weight_av,
# Lifespan ranges, assuming perfect correlation between weight and lifespan ranges
    lifeyears_1=consumption/weight_lower*lifespan_lower/12,
    lifeyears_2=consumption/weight_upper*lifespan_upper/12,
# Min and max lifespan
    lifeyears_lower=min(lifeyears_1,lifeyears_2),
    lifeyears_upper=max(lifeyears_1,lifeyears_2),
# Best guess of average lifespan
    lifeyears_midwl=slaughter_midweight*lifespan_av/12
  )

Produce charts

Fig1: Number of fish slaughtered for EU consumption

Construct chart

Code
fig1 <-   eu_consumption_2021 %>%
  filter(species_group!="Rainbow Trout") %>%
  ggplot(
    aes(
      x=reorder(str_to_title(species_group),slaughter_midweight),
      y=slaughter_midweight,
      ymin=slaughter_lower,
      ymax=slaughter_upper
    )
  ) + 
  geom_col(fill="#1B9E77")+
  geom_errorbar(width=0.2,size=0.3)+
    scale_y_continuous(labels = scales::label_number_si()) +
  theme_light() +
  coord_flip() +
    labs(
    title="Number of fish slaughtered",
    subtitle="Farmed finfish to support EU27 consumption in 2021",
    y="Number slaughtered",
    x="")

Print chart

Code
  fig1

Code
eu_consumption_2021 %>%
  select(species_group,slaughter_midweight,slaughter_lower,slaughter_upper) %>%
  arrange(-slaughter_midweight) %>%
  set_colnames(c("Species","Mid-point", "Lower", "Upper")) %>%
  gt() %>%
  fmt_number(decimals=0,suffixing = TRUE) %>%
  tab_header(title="Number of farmed fish slaughtered to support EU 27 consumption in 2021") %>%
  tab_source_note(source_note = "Mid-point estimate assumes weight is the mean of the upper and lower mean weight estimate.  Lower estimate is based on the upper mean weight estimate.  Upper estimate is based on the lower mean weight estimate.")
Number of farmed fish slaughtered to support EU 27 consumption in 2021
Species Mid-point Lower Upper
Gilthead Seabream 391M 342M 456M
Rainbow Trout (small) 245M 102M 583M
European Seabass 237M 214M 267M
Atlantic Salmon 194M 130M 304M
Freshwater Catfish 102M 68M 204M
Rainbow Trout 83M 43M 1B
Tilapia 76M 50M 159M
Carp 46M 35M 64M
Rainbow Trout (large) 30M 19M 78M
Mid-point estimate assumes weight is the mean of the upper and lower mean weight estimate. Lower estimate is based on the upper mean weight estimate. Upper estimate is based on the lower mean weight estimate.

Fig 2: Share of EU farms where fish are stunned before slaughter

Source: Leaked EU impact assessment document

Construct chart

Code
share_stunned <- tibble(
  species=c("Atlantic Salmon","Rainbow Trout","Carp","Seabream & Seabass"),
  upper=c(1,0.5,0.1,0.05),
  lower=c(0.9,0.2,0,0),
  label=c("> 90%","20% to 50%","< 10%","< 5%")) %>%
  mutate(label_pos=0.5*(upper+lower))



fig2 <- share_stunned %>% 
  ggplot(
    aes(
      x=reorder(species,upper),
      ymin=lower,
      y=label_pos,
      ymax=upper
    )
  ) + 
  geom_errorbar(width=0.5,size=1)+
  geom_linerange(size=8,color="#1B9E77") +
  geom_text(aes(label=label),nudge_x=0.38) +
  scale_y_continuous(labels = scales::percent) +
  theme_light() +
  coord_flip() + 
    labs(
    title="Share of EU farms where fish are stunned",
    x="",
    y="")

Print chart

Code
fig2

Fig 3 - Consumption by country

Construct chart

Code
fig_3_data <-
readRDS("../3_intermediate_data/cons_data.rds") %>%
  filter(country!="United Kingdom") %>%
  mutate(species_group=case_when(
    str_detect(species,"Sea Bream") ~ "Gilthead Seabream",
    str_detect(species,"Sea Bass") ~ "European Seabass",
    str_detect(species,"Salmon") ~ "Atlantic Salmon",
    str_detect(species,"Small") ~ "Rainbow Trout (small)",
    str_detect(species,"Large") ~ "Rainbow Trout (large)",
    str_detect(species,"Carp") ~ "Carp",
    TRUE~"Error")) %>%
  left_join(species_data,by="species_group") %>%
  mutate(
    slaughter_midweight=tons*1E6/weight_av) %>%
  select(species_group,country,slaughter_midweight) %>%
  group_by(country) %>%
  mutate(
    total_cons=sum(slaughter_midweight)
  ) %>%
  ungroup()
Code
fig3 <- fig_3_data %>%
  filter(!species_group %in% c("Atlantic Salmon","Carp","Rainbow Trout (large)")) %>%
  group_by(country) %>%
  mutate(
    total_cons=sum(slaughter_midweight)
  ) %>%
  ungroup() %>%
ggplot(aes(
      y=reorder(country,total_cons),
      x=slaughter_midweight,
      fill=species_group))+
    geom_col()+
    labs(
    title = "Annual number of farmed fish slaughtered to support consumption in EU27",
    x = "Estimated number of individual fish (\"mid-point estimate\")",
    y = "",
    fill = "Species"
  ) +
  scale_x_continuous(labels = label_number(suffix = "M", scale = 1e-6)) +
  scale_fill_brewer(palette = "Dark2",
                    labels = c("European Seabass (2016)", "Gilthead Seabream (2019)", "Small Rainbow Trout (2020)")) +
  theme_light() +
  theme(legend.position = "right")

Print chart

Code
fig3

Export charts into .png format

Code
save_chart("fig1_eu_slaughter_numbers.png",fig1)
save_chart("fig2_stun_shares.png",fig2)
save_chart("fig3_slaughter_by_country_consumption.png",fig3)