Sustainable Finance HW5

library(tidyverse)
Warning: package 'dplyr' was built under R version 4.2.3
Warning: package 'stringr' was built under R version 4.2.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.0
✔ purrr     1.0.2     
── 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(readxl)
library(here)
here() starts at /Users/jiayiding/Desktop/Joy/Johns Hopkins University/Spring 2024/Sustainable Finance:Application and Methods/HW/HW5/SusFinance
library(ggplot2)
library(esquisse)
Warning: package 'esquisse' was built under R version 4.2.3
path_to_sheet <- here("data-raw", "CM_Data_Explorer.xlsx")
path_to_sheet
[1] "/Users/jiayiding/Desktop/Joy/Johns Hopkins University/Spring 2024/Sustainable Finance:Application and Methods/HW/HW5/SusFinance/data-raw/CM_Data_Explorer.xlsx"
read_key_minerals_sheet <- partial(
  .f = read_excel,
  path = path_to_sheet,
  sheet = "2.3 EV",
  col_names = FALSE
)

sheet_header <- read_key_minerals_sheet(range = "A4:W5")
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`
sheet_header_processed <- sheet_header |> 
  t() |>
  as_tibble() |>
  rename(scenario = V1, year = V2) |>
  fill(scenario) |>
  replace_na(list(scenario = "Current Year"))
Warning: The `x` argument of `as_tibble.matrix()` must have unique column names if
`.name_repair` is omitted as of tibble 2.0.0.
ℹ Using compatibility `.name_repair`.
 read_iea_mineral_table <-
  function(condition_name_range, mineral_info_range) {
    condition_name <-
      read_key_minerals_sheet(range = condition_name_range) |>
      pull()
    
    mineral_info <- read_key_minerals_sheet(range = mineral_info_range)
    
    mineral_info_col_names <- names(mineral_info)
    
    sheet_headers_and_col_names <- sheet_header_processed |> 
      add_column(mineral_info_col_names = mineral_info_col_names)
    
    mineral_info_long <- mineral_info |>
      rename(mineral_name = `...1`) |>
      pivot_longer(cols = -mineral_name,
                   names_to = "mineral_info_col_names") |>
      add_column(condition_name)
    
    combined_data <- mineral_info_long |> 
      left_join(sheet_headers_and_col_names, by = join_by(mineral_info_col_names)) |> 
      filter(!is.na(year)) |> 
      mutate(year = as.integer(year)) |> 
      select(mineral_name, condition_name, scenario, year, value)
    
    combined_data
  }

condition1_table <- read_iea_mineral_table(
  condition_name_range = "A7",
  mineral_info_range = "A8:W9"
)
New names:
New names:
• `` -> `...1`
condition2_table <- read_iea_mineral_table(
  condition_name_range = "A22",
  mineral_info_range = "A23:W24"
)
New names:
New names:
• `` -> `...1`
condition3_table <- read_iea_mineral_table(
  condition_name_range = "A37",
  mineral_info_range = "A38:W39"
)
New names:
New names:
• `` -> `...1`
condition4_table <- read_iea_mineral_table(
  condition_name_range = "A52",
  mineral_info_range = "A53:W54"
)
New names:
New names:
• `` -> `...1`
condition5_table <- read_iea_mineral_table(
  condition_name_range = "A67",
  mineral_info_range = "A68:W69"
)
New names:
New names:
• `` -> `...1`
base_condition_table <- read_iea_mineral_table(
  condition_name_range = "A82",
  mineral_info_range = "A83:W84"
)
New names:
New names:
• `` -> `...1`
final_iea_minerals_table <- condition1_table |> 
  bind_rows(condition2_table)|>
  bind_rows(condition3_table)|>
  bind_rows(condition4_table)|>
  bind_rows(condition5_table)|>
  bind_rows(base_condition_table)|>
  filter(!is.na(value))

final_iea_minerals_table
# A tibble: 204 × 5
   mineral_name condition_name            scenario                    year value
   <chr>        <chr>                     <chr>                      <int> <dbl>
 1 Copper       Constrained nickel supply Current Year                2022  381.
 2 Copper       Constrained nickel supply Stated policies scenario    2025  617.
 3 Copper       Constrained nickel supply Stated policies scenario    2030 1389.
 4 Copper       Constrained nickel supply Stated policies scenario    2035 1736.
 5 Copper       Constrained nickel supply Stated policies scenario    2040 2233.
 6 Copper       Constrained nickel supply Stated policies scenario    2045 2418.
 7 Copper       Constrained nickel supply Stated policies scenario    2050 2313.
 8 Copper       Constrained nickel supply Announced pledges scenario  2025  732.
 9 Copper       Constrained nickel supply Announced pledges scenario  2030 2113.
10 Copper       Constrained nickel supply Announced pledges scenario  2035 3587.
# ℹ 194 more rows

Visualization #1

It shows that under Net Zero Emissions by 2050 scenario, mineral demand is the highest while under states policies scenario, mineral demand growth is comparatively flat.

p1 <- final_iea_minerals_table|>
  filter(mineral_name == "Copper")|>
  filter(condition_name == "STEPS - Base case")|>
  ggplot(aes(x = year, y = value, color = scenario)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Base case EV Demand for Copper Under Different Scenarios", 
    x = "Scenarios", 
    y = "Mineral demand(kilotons)"
  ) +
  theme(plot.title = element_text(face = "bold"), 
        axis.text.x = element_text(angle = 30, hjust = 1))

p2 <- final_iea_minerals_table|>
  filter(mineral_name == "Cobalt")|>
  filter(condition_name == "STEPS - Base case")|>
  ggplot(aes(x = year, y = value, color = scenario)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Base case EV Demand for Cobalt Under Different Scenarios", 
    x = "Scenarios", 
    y = "Mineral demand(kilotons)"
  ) +
  theme(plot.title = element_text(face = "bold"), 
        axis.text.x = element_text(angle = 30, hjust = 1))
p1

p2

Visualization #2

It shows the differences in copper and cobalt demand under different conditions. When there is constrained nickel supply, copper’s volume has significantly increased compared to others while cobalt shows the opposite trend. Copper might be substitute of nickel while cobalt is complementary of nickel.

desired_corder <- c("STEPS - Base case", "Lower battery sizes",
                   "Wider use of silicon-rich anodes", "Faster uptake of solid state batteries",
                   "Constrained nickel supply","Limited battery size reduction")
p3 <- final_iea_minerals_table$condition_name <- factor(final_iea_minerals_table$condition_name, levels = desired_corder)
final_iea_minerals_table|>
  filter(mineral_name == "Copper")|>
  ggplot(aes(x = year, y = value, colour = scenario)) +
  geom_point(shape = "circle", size = 1.5) +
  geom_line()+
  scale_color_hue(direction = 1) +
  labs(
    title = "Changes in EV Demand for Copper Under Different Conditions", 
    x = "Year", 
    y = "Mineral demand(kilotons)"
  ) +
  theme(plot.title = element_text(face = "bold"), 
        axis.text.x = element_text(angle = 30, hjust = 1))+
  facet_wrap(vars(condition_name))

p3
  [1] Constrained nickel supply             
  [2] Constrained nickel supply             
  [3] Constrained nickel supply             
  [4] Constrained nickel supply             
  [5] Constrained nickel supply             
  [6] Constrained nickel supply             
  [7] Constrained nickel supply             
  [8] Constrained nickel supply             
  [9] Constrained nickel supply             
 [10] Constrained nickel supply             
 [11] Constrained nickel supply             
 [12] Constrained nickel supply             
 [13] Constrained nickel supply             
 [14] Constrained nickel supply             
 [15] Constrained nickel supply             
 [16] Constrained nickel supply             
 [17] Constrained nickel supply             
 [18] Constrained nickel supply             
 [19] Constrained nickel supply             
 [20] Constrained nickel supply             
 [21] Constrained nickel supply             
 [22] Constrained nickel supply             
 [23] Constrained nickel supply             
 [24] Constrained nickel supply             
 [25] Constrained nickel supply             
 [26] Constrained nickel supply             
 [27] Constrained nickel supply             
 [28] Constrained nickel supply             
 [29] Constrained nickel supply             
 [30] Constrained nickel supply             
 [31] Constrained nickel supply             
 [32] Constrained nickel supply             
 [33] Constrained nickel supply             
 [34] Constrained nickel supply             
 [35] Constrained nickel supply             
 [36] Constrained nickel supply             
 [37] Constrained nickel supply             
 [38] Constrained nickel supply             
 [39] Wider use of silicon-rich anodes      
 [40] Wider use of silicon-rich anodes      
 [41] Wider use of silicon-rich anodes      
 [42] Wider use of silicon-rich anodes      
 [43] Wider use of silicon-rich anodes      
 [44] Wider use of silicon-rich anodes      
 [45] Wider use of silicon-rich anodes      
 [46] Wider use of silicon-rich anodes      
 [47] Wider use of silicon-rich anodes      
 [48] Wider use of silicon-rich anodes      
 [49] Wider use of silicon-rich anodes      
 [50] Wider use of silicon-rich anodes      
 [51] Wider use of silicon-rich anodes      
 [52] Wider use of silicon-rich anodes      
 [53] Wider use of silicon-rich anodes      
 [54] Wider use of silicon-rich anodes      
 [55] Wider use of silicon-rich anodes      
 [56] Wider use of silicon-rich anodes      
 [57] Wider use of silicon-rich anodes      
 [58] Wider use of silicon-rich anodes      
 [59] Wider use of silicon-rich anodes      
 [60] Wider use of silicon-rich anodes      
 [61] Wider use of silicon-rich anodes      
 [62] Wider use of silicon-rich anodes      
 [63] Wider use of silicon-rich anodes      
 [64] Wider use of silicon-rich anodes      
 [65] Wider use of silicon-rich anodes      
 [66] Wider use of silicon-rich anodes      
 [67] Wider use of silicon-rich anodes      
 [68] Wider use of silicon-rich anodes      
 [69] Wider use of silicon-rich anodes      
 [70] Wider use of silicon-rich anodes      
 [71] Wider use of silicon-rich anodes      
 [72] Wider use of silicon-rich anodes      
 [73] Wider use of silicon-rich anodes      
 [74] Wider use of silicon-rich anodes      
 [75] Wider use of silicon-rich anodes      
 [76] Wider use of silicon-rich anodes      
 [77] Faster uptake of solid state batteries
 [78] Faster uptake of solid state batteries
 [79] Faster uptake of solid state batteries
 [80] Faster uptake of solid state batteries
 [81] Faster uptake of solid state batteries
 [82] Faster uptake of solid state batteries
 [83] Faster uptake of solid state batteries
 [84] Faster uptake of solid state batteries
 [85] Faster uptake of solid state batteries
 [86] Faster uptake of solid state batteries
 [87] Faster uptake of solid state batteries
 [88] Faster uptake of solid state batteries
 [89] Faster uptake of solid state batteries
 [90] Faster uptake of solid state batteries
 [91] Faster uptake of solid state batteries
 [92] Faster uptake of solid state batteries
 [93] Faster uptake of solid state batteries
 [94] Faster uptake of solid state batteries
 [95] Faster uptake of solid state batteries
 [96] Faster uptake of solid state batteries
 [97] Faster uptake of solid state batteries
 [98] Faster uptake of solid state batteries
 [99] Faster uptake of solid state batteries
[100] Faster uptake of solid state batteries
[101] Faster uptake of solid state batteries
[102] Faster uptake of solid state batteries
[103] Faster uptake of solid state batteries
[104] Faster uptake of solid state batteries
[105] Faster uptake of solid state batteries
[106] Faster uptake of solid state batteries
[107] Faster uptake of solid state batteries
[108] Faster uptake of solid state batteries
[109] Faster uptake of solid state batteries
[110] Faster uptake of solid state batteries
[111] Faster uptake of solid state batteries
[112] Faster uptake of solid state batteries
[113] Faster uptake of solid state batteries
[114] Faster uptake of solid state batteries
[115] Lower battery sizes                   
[116] Lower battery sizes                   
[117] Lower battery sizes                   
[118] Lower battery sizes                   
[119] Lower battery sizes                   
[120] Lower battery sizes                   
[121] Lower battery sizes                   
[122] Lower battery sizes                   
[123] Lower battery sizes                   
[124] Lower battery sizes                   
[125] Lower battery sizes                   
[126] Lower battery sizes                   
[127] Lower battery sizes                   
[128] Lower battery sizes                   
[129] Lower battery sizes                   
[130] Lower battery sizes                   
[131] Lower battery sizes                   
[132] Lower battery sizes                   
[133] Lower battery sizes                   
[134] Lower battery sizes                   
[135] Lower battery sizes                   
[136] Lower battery sizes                   
[137] Lower battery sizes                   
[138] Lower battery sizes                   
[139] Lower battery sizes                   
[140] Lower battery sizes                   
[141] Lower battery sizes                   
[142] Lower battery sizes                   
[143] Lower battery sizes                   
[144] Lower battery sizes                   
[145] Lower battery sizes                   
[146] Lower battery sizes                   
[147] Lower battery sizes                   
[148] Lower battery sizes                   
[149] Lower battery sizes                   
[150] Lower battery sizes                   
[151] Lower battery sizes                   
[152] Lower battery sizes                   
[153] Limited battery size reduction        
[154] Limited battery size reduction        
[155] Limited battery size reduction        
[156] Limited battery size reduction        
[157] Limited battery size reduction        
[158] Limited battery size reduction        
[159] Limited battery size reduction        
[160] Limited battery size reduction        
[161] Limited battery size reduction        
[162] Limited battery size reduction        
[163] Limited battery size reduction        
[164] Limited battery size reduction        
[165] Limited battery size reduction        
[166] Limited battery size reduction        
[167] STEPS - Base case                     
[168] STEPS - Base case                     
[169] STEPS - Base case                     
[170] STEPS - Base case                     
[171] STEPS - Base case                     
[172] STEPS - Base case                     
[173] STEPS - Base case                     
[174] STEPS - Base case                     
[175] STEPS - Base case                     
[176] STEPS - Base case                     
[177] STEPS - Base case                     
[178] STEPS - Base case                     
[179] STEPS - Base case                     
[180] STEPS - Base case                     
[181] STEPS - Base case                     
[182] STEPS - Base case                     
[183] STEPS - Base case                     
[184] STEPS - Base case                     
[185] STEPS - Base case                     
[186] STEPS - Base case                     
[187] STEPS - Base case                     
[188] STEPS - Base case                     
[189] STEPS - Base case                     
[190] STEPS - Base case                     
[191] STEPS - Base case                     
[192] STEPS - Base case                     
[193] STEPS - Base case                     
[194] STEPS - Base case                     
[195] STEPS - Base case                     
[196] STEPS - Base case                     
[197] STEPS - Base case                     
[198] STEPS - Base case                     
[199] STEPS - Base case                     
[200] STEPS - Base case                     
[201] STEPS - Base case                     
[202] STEPS - Base case                     
[203] STEPS - Base case                     
[204] STEPS - Base case                     
6 Levels: STEPS - Base case ... Limited battery size reduction
p4 <- final_iea_minerals_table|>
  filter(mineral_name == "Cobalt")|>
  ggplot(aes(x = year, y = value, colour = scenario)) +
  geom_point(shape = "circle", size = 1.5) +
  geom_line()+
  scale_color_hue(direction = 1) +
  labs(
    title = "Changes in EV Demand for Cobalt Under Different Conditions", 
    x = "Year", 
    y = "Mineral demand(kilotons)"
  ) +
  theme(plot.title = element_text(face = "bold"), 
        axis.text.x = element_text(angle = 30, hjust = 1))+
  facet_wrap(vars(condition_name))
p4

Visualization #3

It compare the copper and cobalt demand across different scenarios for each year. Net Zero Emission by 2050 scenario has the most demand for minerals.

desired_order <- c("Current Year","Stated policies scenario",
                   "Announced pledges scenario", 
                   "Net Zero Emissions by 2050 scenario")
final_iea_minerals_table$scenario <- factor(final_iea_minerals_table$scenario, levels = desired_order)

p5 <- final_iea_minerals_table|>
  ggplot(aes(x = scenario, y = value, fill=mineral_name)) +
  geom_bar(stat = "identity") +
  labs(title = "EV Mineral Demand different years under different scenarios",
       x = "Scenario",
       y = "Demand") +
  theme(plot.title = element_text(face = "bold"), 
        axis.text.x = element_text(angle = 30, hjust = 1))+
  facet_wrap(vars(year))
p5

Visualization #4

Visualize annual growth rate of copper and cobalt demand under the Net Zero Emissions by 2050 scenario. It shows that the growth rate generally decreases overtime.

p6 <- final_iea_minerals_table|>
  filter(scenario == "Net Zero Emissions by 2050 scenario")|>
  filter(mineral_name == "Copper")|>
  filter(condition_name == "STEPS - Base case")|>
  arrange(year) |>
  mutate(growth_rate = (value/ lag(value) - 1) * 100)|>
  ggplot(aes(x = year, y=growth_rate)) +
  geom_point() +
  geom_line() +
  labs(title="Yearly Growth Rate of Copper Demand", x="Year", y="Growth Rate (%)") +
  theme_minimal()
p6
Warning: Removed 1 rows containing missing values (`geom_point()`).
Warning: Removed 1 row containing missing values (`geom_line()`).

p7 <- final_iea_minerals_table|>
  filter(scenario == "Net Zero Emissions by 2050 scenario")|>
  filter(mineral_name == "Cobalt")|>
  filter(condition_name == "STEPS - Base case")|>
  arrange(year) |>
  mutate(growth_rate = (value/ lag(value) - 1) * 100)|>
  ggplot(aes(x = year, y=growth_rate)) +
  geom_point() +
  geom_line() +
  labs(title="Yearly Growth Rate of Cobalt Demand", x="Year", y="Growth Rate (%)") +
  theme_minimal()
p7
Warning: Removed 1 rows containing missing values (`geom_point()`).
Removed 1 row containing missing values (`geom_line()`).

Visualization #5

Visualize the cumulative demand of Copper and Cobalt over the years to see the total demand over time under Stated policies scenario.

p8 <- final_iea_minerals_table|>
  filter(scenario == "Stated policies scenario")|>
  filter(mineral_name == "Copper")|>
  filter(condition_name == "STEPS - Base case")|>
  arrange(year) |>
  mutate(CumulativeDemand = cumsum(value))|>
  ggplot( aes(x=year, y=CumulativeDemand)) +
  geom_area(fill="lightblue", alpha=0.5) +
  geom_line(color="deepskyblue") +
  labs(title="Cumulative Demand of Copper Over Years", x="Year", y="Cumulative Demand") +
  theme_minimal()
p8

p9 <- final_iea_minerals_table|>
  filter(mineral_name == "Cobalt")|>
  filter(scenario == "Stated policies scenario")|>
  filter(condition_name == "STEPS - Base case")|>
  arrange(year) |>
  mutate(CumulativeDemand = cumsum(value))|>
  ggplot( aes(x=year, y=CumulativeDemand)) +
  geom_area(fill="lightblue", alpha=0.5) +
  geom_line(color="deepskyblue") +
  labs(title="Cumulative Demand of Cobalt Over Years", x="Year", y="Cumulative Demand") +
  theme_minimal()
p9