Ticha Sus Fin HW5

Ticha Sus Fin HW 5

Data Tidying

Your boss knows that they will be asking her about how the implications of the electric vehicle (EV) market and policy choices on the demand for copper and cobalt.

  1. Use the workflow developed in this chapter to import and tidy worksheet 2.3 EV from the dataset.

Load Relevant Libraries

library(dplyr)
Warning: package 'dplyr' was built under R version 4.2.3

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(tidyverse)
Warning: package 'tidyr' was built under R version 4.2.3
Warning: package 'readr' was built under R version 4.2.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ forcats   1.0.0     ✔ readr     2.1.5
✔ ggplot2   3.4.4     ✔ stringr   1.5.0
✔ lubridate 1.9.3     ✔ tibble    3.2.1
✔ purrr     1.0.1     ✔ tidyr     1.3.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(scales)
Warning: package 'scales' was built under R version 4.2.3

Attaching package: 'scales'

The following object is masked from 'package:purrr':

    discard

The following object is masked from 'package:readr':

    col_factor
library(readxl)
library(openxlsx)
library(RColorBrewer)

Reading Excel File

setwd("~/Desktop/Sus Fin App & Meth/Ticha_Sus_Fin_HW5/Data_Raw")
CM_Data_Explorer <- read_excel("CM_Data_Explorer.xlsx", 
                               sheet = "2.3 EV", col_names = FALSE)
New names:
• `` -> `...1`
• `` -> `...2`
• `` -> `...3`
• `` -> `...4`
• `` -> `...5`
• `` -> `...6`
• `` -> `...7`
• `` -> `...8`
• `` -> `...9`
• `` -> `...10`
• `` -> `...11`
• `` -> `...12`
• `` -> `...13`
• `` -> `...14`
• `` -> `...15`
• `` -> `...16`
• `` -> `...17`
• `` -> `...18`
• `` -> `...19`
• `` -> `...20`
• `` -> `...21`
• `` -> `...22`
• `` -> `...23`
# Make a Raw Data File in Case We need to come back
CM_Data_Raw <- CM_Data_Explorer

Tidying and Adjusting Raw Data

# Make Scenario Columns
CM_Data_Explorer[, c(3, 10, 17)] <- lapply(CM_Data_Explorer[, c(3, 10, 17)], as.character)
CM_Data_Explorer[, 3] <- "Stated policies scenario"
CM_Data_Explorer[, 10] <-"Announced pledges scenario"
CM_Data_Explorer[, 17] <-"Net Zero Emissions by 2050 scenario"

# Make Row 4 Into Column Names
colnames(CM_Data_Explorer) <- as.character(unlist(CM_Data_Explorer[4, ]))
colnames(CM_Data_Explorer)[1]<- "Minerals"
# Remove rows 1 through 5 and then filter out rows where column 1 is NA
CM_Data_Explorer <- CM_Data_Explorer[-(1:5), ][!is.na(CM_Data_Explorer[-(1:5), 1]), ]

# Make Technology Column
CM_Data_Explorer[, 'Situation'] = NA
CM_Data_Explorer$Situation[1:13] <- "Constrained nickel supply"
CM_Data_Explorer$Situation[14:26] <- "Wider use of silicon-rich anodes"
CM_Data_Explorer$Situation[27:39] <- "Faster uptake of solid state batteries"
CM_Data_Explorer$Situation[40:52] <- "Lower battery sizes"
CM_Data_Explorer$Situation[53:65] <- "Limited battery size reduction"
CM_Data_Explorer$Situation[66:78] <- "STEPS - Base case"

# Delete Heading Rows
CM_Data_Explorer <- CM_Data_Explorer[!is.na(CM_Data_Explorer$`2022`), ]
head(CM_Data_Explorer)
# A tibble: 6 × 24
  Minerals  `2022` `Stated policies scenario` `2025` `2030` `2035` `2040` `2045`
  <chr>      <dbl> <chr>                      <chr>   <dbl>  <dbl>  <dbl>  <dbl>
1 Copper     381.  Stated policies scenario   616.9… 1389.  1736.  2233.  2418. 
2 Cobalt      63.5 Stated policies scenario   61.21…   38.0   29.1   35.4   40.9
3 Graphite   557.  Stated policies scenario   935.6… 1590.  1782.  1691.  1492. 
4 Lithium     69.6 Stated policies scenario   122.5…  219.   307.   407.   450. 
5 Manganese   74.5 Stated policies scenario   53.85…  156.   336.   533.   712. 
6 Nickel     313.  Stated policies scenario   553.7…  513.   589.   630.   692. 
# ℹ 16 more variables: `2050` <dbl>, `Announced pledges scenario` <chr>,
#   `2025` <chr>, `2030` <dbl>, `2035` <dbl>, `2040` <dbl>, `2045` <dbl>,
#   `2050` <dbl>, `Net Zero Emissions by 2050 scenario` <chr>, `2025` <chr>,
#   `2030` <dbl>, `2035` <dbl>, `2040` <dbl>, `2045` <dbl>, `2050` <dbl>,
#   Situation <chr>

Subsetting and Stacking Columns

### SUBSET DATA & STACK ######
# Subset 1
STEPS <- CM_Data_Explorer[, c(1:9, 24)]
# Subset 2
APS <- CM_Data_Explorer[, c(1:2, 10:16, 24)]
colnames(APS)[3:9] <- colnames(STEPS)[3:9]
# Subset 3
NZE <- CM_Data_Explorer[, c(1:2, 17:24)]
colnames(NZE)[3:9] <- colnames(STEPS)[3:9]
# Stack Subsets 1-3
stacked_data <- rbind(STEPS, APS, NZE)

### Current Year DATA
current_year <- unique(stacked_data[, c(1:3, 10)])
current_year$Year <- 2022
colnames(current_year)[2] <- "Value"
colnames(current_year)[3] <- "Scenario"
head(current_year)
# A tibble: 6 × 5
  Minerals  Value Scenario                 Situation                  Year
  <chr>     <dbl> <chr>                    <chr>                     <dbl>
1 Copper    381.  Stated policies scenario Constrained nickel supply  2022
2 Cobalt     63.5 Stated policies scenario Constrained nickel supply  2022
3 Graphite  557.  Stated policies scenario Constrained nickel supply  2022
4 Lithium    69.6 Stated policies scenario Constrained nickel supply  2022
5 Manganese  74.5 Stated policies scenario Constrained nickel supply  2022
6 Nickel    313.  Stated policies scenario Constrained nickel supply  2022

Tidying Clean Scenarios and Saving File

clean_scenarios <- stacked_data[,c(1, 3:10)]
colnames(clean_scenarios)[2] <- "Scenario"
clean_scenarios[, 3:8] <- lapply(clean_scenarios[, 3:8], as.numeric)
clean_scenarios_long <- pivot_longer(clean_scenarios, cols = 3:8, names_to = "Year", values_to = "Value")

# Attach Current Year To the LONG SCENARIOS DATASET
all_clean_long <- rbind(clean_scenarios_long,current_year)

head(all_clean_long)
# A tibble: 6 × 5
  Minerals Scenario                 Situation                 Year  Value
  <chr>    <chr>                    <chr>                     <chr> <dbl>
1 Copper   Stated policies scenario Constrained nickel supply 2025   617.
2 Copper   Stated policies scenario Constrained nickel supply 2030  1389.
3 Copper   Stated policies scenario Constrained nickel supply 2035  1736.
4 Copper   Stated policies scenario Constrained nickel supply 2040  2233.
5 Copper   Stated policies scenario Constrained nickel supply 2045  2418.
6 Copper   Stated policies scenario Constrained nickel supply 2050  2313.
#### SAVE CLEANED DATA
file_path <- "~/Desktop/Sus Fin App & Meth/Ticha_Sus_Fin_HW5/all_clean_long.xlsx"
write.xlsx(all_clean_long, file = file_path)

Creating New Dataframes with Copper and Cobalt

### FILTER OUT COPPER AND COBALT
CoCo_long <- all_clean_long %>%
  filter(Minerals %in% c("Copper", "Cobalt"))
file_path <- "~/Desktop/Sus Fin App & Meth/Ticha_Sus_Fin_HW5/CoCo_long.xlsx"
write.xlsx(CoCo_long, file = file_path)

#### FILTER OUT COBALT
Cobalt_long <- all_clean_long %>%
  filter(Minerals == "Cobalt") %>%
  mutate(Year = as.numeric(as.character(Year))) %>%
  select(-Minerals)

#### FILTER OUT COPPER
Copper_long <- all_clean_long %>%
  filter(Minerals == "Copper") %>%
  mutate(Year = as.numeric(as.character(Year))) %>%
  select(-Minerals)

head(CoCo_long)
# A tibble: 6 × 5
  Minerals Scenario                 Situation                 Year  Value
  <chr>    <chr>                    <chr>                     <chr> <dbl>
1 Copper   Stated policies scenario Constrained nickel supply 2025   617.
2 Copper   Stated policies scenario Constrained nickel supply 2030  1389.
3 Copper   Stated policies scenario Constrained nickel supply 2035  1736.
4 Copper   Stated policies scenario Constrained nickel supply 2040  2233.
5 Copper   Stated policies scenario Constrained nickel supply 2045  2418.
6 Copper   Stated policies scenario Constrained nickel supply 2050  2313.
head(Cobalt_long)
# A tibble: 6 × 4
  Scenario                 Situation                  Year Value
  <chr>                    <chr>                     <dbl> <dbl>
1 Stated policies scenario Constrained nickel supply  2025  61.2
2 Stated policies scenario Constrained nickel supply  2030  38.0
3 Stated policies scenario Constrained nickel supply  2035  29.1
4 Stated policies scenario Constrained nickel supply  2040  35.4
5 Stated policies scenario Constrained nickel supply  2045  40.9
6 Stated policies scenario Constrained nickel supply  2050  47.4
head(Copper_long)
# A tibble: 6 × 4
  Scenario                 Situation                  Year Value
  <chr>                    <chr>                     <dbl> <dbl>
1 Stated policies scenario Constrained nickel supply  2025  617.
2 Stated policies scenario Constrained nickel supply  2030 1389.
3 Stated policies scenario Constrained nickel supply  2035 1736.
4 Stated policies scenario Constrained nickel supply  2040 2233.
5 Stated policies scenario Constrained nickel supply  2045 2418.
6 Stated policies scenario Constrained nickel supply  2050 2313.
  1. Use the tidied dataset to come up with 5 compelling data visualizations that illustrate key actionable insights about how policy scenarios, and technological scenarios will impact demand for copper and cobalt.

Visualizations

Visualization I: BOXPLOT

ggplot(CoCo_long) +
  aes(x = Value, y = Situation, fill = Year) +
  geom_boxplot() +
  scale_fill_hue(direction = 1) + 
  labs(
    title = "Projected Demand for Critical Minerals (kt)",
    subtitle = "Comparative analysis across technological scenarios and years",
    x = "Projected Demand (kt)",
    y = "Technological Scenario",
    fill = "Year"
  ) +
  guides(fill = guide_legend(title.position = "left", title.hjust = 0.5)) +
  theme_minimal() +
  theme(
    legend.position = "bottom", 
    text = element_text(size = 12), 
    axis.title = element_text(size = 14), 
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 11),
    strip.text.x = element_text(size = 12) 
  ) +
  facet_wrap(vars(Minerals), scales = "free_x", ncol = 2)
Warning: Removed 24 rows containing non-finite values (`stat_boxplot()`).

Key Takeaways:

  • Copper demand spans a broader range with significant increases projected in the future, indicating its critical role in technology advancements.

  • Cobalt’s demand, while lower than copper’s, shows variability across scenarios, suggesting sensitivity to specific technological trends.

  • The presence of outliers, especially in the later years, may reflect the increasing difficulty of making long-term projections due to the potential for unforeseen technological advancements or market changes.

  • The variability within scenarios for both minerals suggests there is uncertainty about how technology will evolve and how this will impact demand. For instance, if solid-state batteries are adopted faster, this could significantly change the demand landscape for cobalt and copper.

Visualization II: Line Plot for COBALT

ggplot(Cobalt_long) +
  aes(x = Year, y = Value, colour = Scenario) +
  geom_line() +
  scale_color_hue(direction = 1, l = 50) +
  labs(
    title = "Projected Demand for Cobalt Over Years",
    subtitle = "Analysis Across Different Technological Scenarios",
    x = "Year",
    y = "Projected Demand for Cobalt (kt)",
    colour = "IEA Climate Scenario"
  ) +
  guides(colour = guide_legend(override.aes = list(size = 4))) +
  theme_minimal() +
  theme(
    legend.position = "right", 
    legend.title.align = 0.5,
    text = element_text(size = 10),
    axis.title = element_text(size = 10), 
    plot.title = element_text(size = 10, face = "bold"),
    plot.subtitle = element_text(size = 8),
    strip.text = element_text(size = 6), 
    legend.text = element_text(size = 8)
  ) +
  facet_wrap(vars(Situation), scales = "free_y", ncol = 2)

Key Takeaways:

  • Across all scenarios, there is a clear upward trend in the demand for cobalt over the years, indicating an overall growth in the need for cobalt from 2020 to 2050.

  • The “Constrained nickel supply” scenario projects the highest demand for cobalt, peaking above 100 kt, suggesting that a nickel constraint could increase reliance on cobalt. Meanwhile, the “Lower battery sizes” and “Wider use of silicon-rich anodes” scenarios also show significant demand growth, though not as pronounced as the “Constrained nickel supply” scenario.

  • Under the “Announced pledges scenario” (green line), the demand trajectory is moderately increasing, while the “Net Zero Emissions by 2050 scenario” (blue line) shows the lowest growth, indicating that achieving net zero emissions could potentially involve reduced cobalt dependency.

  • The demand for cobalt varies widely across the scenarios, with the “Stated policies scenario” showing a demand ranging from approximately 25 kt to just over 250 kt, and the “Announced pledges scenario” and “Net Zero Emissions by 2050 scenario” showing a range from around 25 kt to 200 kt and 150 kt, respectively, by 2050.

Visualization III: Line Plot for Copper

ggplot(Copper_long) +
  aes(x = Year, y = Value, colour = Scenario) +
  geom_line() +
  scale_color_hue(direction = 1, l = 50) +
  labs(
    title = "Projected Demand for Copper Over Years",
    subtitle = "Analysis Across Different Technological Scenarios",
    x = "Year",
    y = "Projected Demand for Copper (kt)",
    colour = "IEA Climate Scenario"
  ) +
  guides(colour = guide_legend(override.aes = list(size = 4))) +
  theme_minimal() +
  theme(
    legend.position = "right", 
    legend.title.align = 0.5,
    text = element_text(size = 10),
    axis.title = element_text(size = 10), 
    plot.title = element_text(size = 10, face = "bold"),
    plot.subtitle = element_text(size = 8),
    strip.text = element_text(size = 6), 
    legend.text = element_text(size = 8)
  ) +
  facet_wrap(vars(Situation), scales = "free_y", ncol = 2)

Key Takeaways:

  • The demand for copper is expected to increase over time across all technological and policy scenarios.

  • Scenarios like “Constrained nickel supply” and “Wider use of silicon-rich anodes” predict a higher demand for copper, suggesting that these technologies may rely more heavily on copper.

  • Scenarios like “Lower battery sizes” and “Limited battery size reduction” show different growth rates, indicating that the size of batteries has a significant impact on copper demand.

  • We can see that Announced Pledges Scenario is trailing closely behind Net Zero Emissions by 2050 Scenario, with the two converging at 2050, while the STEPS scenario accounts for about a third of the NZE demand across all years.

Visualization IV: Growth Rate Line Plot

Generate Growth Rates

#### Generate Growth Rate for Cobalt
Cobalt_growth <- Cobalt_long %>%
  filter(Year %in% c(2022, 2025, 2030, 2035, 2040, 2045, 2050)) %>%
  arrange(Situation, Scenario, Year) %>%
  group_by(Situation, Scenario) %>%
  mutate(Growth = (Value / lag(Value) - 1) * 100) %>%
  filter(!is.na(Growth))
  
#### Generate Growth Rate for Copper
Copper_growth <- Copper_long %>%
  filter(Year %in% c(2022, 2025, 2030, 2035, 2040, 2045, 2050)) %>%
  arrange(Situation, Scenario, Year) %>%
  group_by(Situation, Scenario) %>%
  mutate(Growth = (Value / lag(Value) - 1) * 100) %>%
  filter(!is.na(Growth))

#### Combining growth rates
Cobalt_growth$Mineral <- 'Cobalt'
Copper_growth$Mineral <- 'Copper'

# Combine the two data frames
combined_growth <- rbind(Cobalt_growth, Copper_growth)

Graph Growth Line Plots

base_colors <- c("Cobalt" = "#0047ab", # Deep blue for Cobalt
                 "Copper" = "#b87333") # Reddish-brown for Copper

# Plotting
ggplot(combined_growth, aes(x = Year, y = Growth, color = Mineral, linetype = Scenario)) +
  geom_line() +
  scale_color_manual(values = base_colors) +
  labs(title = "Year-Over-Year Growth in Projected Demand for Cobalt and Copper",
       x = "Year",
       y = "Growth (%)",
       color = "Mineral",
       linetype = "Scenario") +
  theme_minimal() +
  theme(legend.position = "bottom") +
  facet_wrap(~ Situation, scales = "free_y", ncol = 3) +
  guides(color = guide_legend(nrow = 2, byrow = TRUE),
         linetype = guide_legend(nrow = 3, byrow = TRUE))

Key Takeaways:

  • Both Cobalt and Copper experience a sharp increase in growth rate around 2025, followed by a significant decline. This suggests that there may be a technological or market development around that time driving a surge in demand, which then stabilizes or decreases as the market becomes saturated or as alternative technologies emerge.

  • The various scenarios depicted—such as “Constrained nickel supply,” “Faster uptake of solid-state batteries,” and “Wider use of silicon-rich anodes”—each have a distinct impact on the demand growth rate for both minerals. The scenarios likely represent different technological or policy developments, each altering the projected demand trajectory for Cobalt and Copper.

  • The trends for Cobalt and Copper diverge under certain scenarios, indicating that the two minerals may not be equally impacted by the same market or technological changes. For example, in the scenario “Limited battery size reduction,” the demand for Cobalt seems to decline sharply after 2025, while Copper demand growth experiences a less dramatic decrease.

  • The “Net Zero Emissions by 2050 scenario” and “Stated policies scenario” lines suggest that policy initiatives have a substantial effect on the demand for these minerals. The steeper decline in growth rate under the “Net Zero Emissions by 2050 scenario” could reflect a transition to technologies that are less reliant on these minerals, or more efficient in their use.

Visualization V: Net Zero Emissions by 2050 Scenario Breakdown

CoCo_NZE <- CoCo_long %>%
  filter(Scenario == "Net Zero Emissions by 2050 scenario")


ggplot(CoCo_NZE, aes(x = Year, y = Value, fill = Situation)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Annual Values of Cobalt and Copper in the Net Zero Emissions by 2050 Scenario",
       x = "Year",
       y = "Projected Demand (in kt)",
       fill = "Technological Situation") +
  facet_wrap(~ Minerals) +
  theme_minimal() +
  theme(legend.position = "bottom") +
  guides(fill = guide_legend(ncol = 2)) +
  theme(plot.title = element_text(hjust = 0.5)) # Center the plot title

Key Takeaways:

  • The projected demand for both Cobalt and Copper experiences rapid growth until around 2030, after which the rate of increase appears to stabilize or slow down, particularly for Cobalt.

  • While both minerals show growth in demand, Copper demand is significantly higher than Cobalt in the later years, especially noticeable after 2040 in the “Net Zero Emissions by 2050 Scenario”.

  • Different technological situations lead to varying demand projections, with some situations like “Constrained nickel supply” and “Faster uptake of solid-state batteries” resulting in higher projected demand for both minerals.

  • The “Constrained nickel supply” and “Faster uptake of solid state batteries” situations have the most significant impact on increasing demand, suggesting these factors are key drivers in the market for these minerals.