── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.4.4 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ 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) # for reading excel files#install.packages("here") # install the package if you haven't yetlibrary(here) # for using relative file paths
here() starts at /Users/shenyuhao/Desktop/JHU SAIS/Spring/Sustainable Finance/Coding Assignment 5
read_key_minerals_sheet <-partial(# provide the function, in this case readxl::read_excel().f = read_excel,# provide any arguments you want filled inpath = path_to_sheet,sheet ="1 Total demand for key minerals",col_names =FALSE)# now all we have to do is provide the rangesheet_header <-read_key_minerals_sheet(range ="A4:W5")
# A tibble: 2 × 23
...1 ...2 ...3 ...4 ...5 ...6 ...7 ...8 ...9 ...10 ...11 ...12 ...13
<lgl> <dbl> <lgl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <lgl> <chr> <dbl> <dbl>
1 NA NA NA State… NA NA NA NA NA NA Anno… NA NA
2 NA 2022 NA 2025 2030 2035 2040 2045 2050 NA 2025 2030 2035
# ℹ 10 more variables: ...14 <dbl>, ...15 <dbl>, ...16 <dbl>, ...17 <lgl>,
# ...18 <chr>, ...19 <dbl>, ...20 <dbl>, ...21 <dbl>, ...22 <dbl>,
# ...23 <dbl>
Tidying the headers
sheet_header_processed <- sheet_header |># transpose the datat() |># turn it back into a tibbleas_tibble() |># make them meaningfulrename(scenario = V1, year = V2) |># fill scenario downfill(scenario) |>#insert "Current" at topreplace_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`.
sheet_header_processed
# A tibble: 23 × 2
scenario year
<chr> <chr>
1 Current Year <NA>
2 Current Year 2022
3 Current Year <NA>
4 Stated policies scenario 2025
5 Stated policies scenario 2030
6 Stated policies scenario 2035
7 Stated policies scenario 2040
8 Stated policies scenario 2045
9 Stated policies scenario 2050
10 Stated policies scenario <NA>
# ℹ 13 more rows
#add the names as a column with the sheet header data we tidied abovesheet_headers_and_col_names <- sheet_header_processed |>add_column(mineral_info_col_names = mineral_info_col_names)sheet_headers_and_col_names
# A tibble: 23 × 3
scenario year mineral_info_col_names
<chr> <chr> <chr>
1 Current Year <NA> ...1
2 Current Year 2022 ...2
3 Current Year <NA> ...3
4 Stated policies scenario 2025 ...4
5 Stated policies scenario 2030 ...5
6 Stated policies scenario 2035 ...6
7 Stated policies scenario 2040 ...7
8 Stated policies scenario 2045 ...8
9 Stated policies scenario 2050 ...9
10 Stated policies scenario <NA> ...10
# ℹ 13 more rows
# pivot the mineral info into a tidy long-format, and we’ll add the mineral namemineral_info_long <- mineral_info |>rename(indicator =`...1`) |>pivot_longer(cols =-indicator,names_to ="mineral_info_col_names") |>add_column(mineral_name)mineral_info_long
# A tibble: 242 × 4
indicator mineral_info_col_names value mineral_name
<chr> <chr> <dbl> <chr>
1 Solar PV ...2 682. Copper
2 Solar PV ...3 NA Copper
3 Solar PV ...4 779. Copper
4 Solar PV ...5 907. Copper
5 Solar PV ...6 925. Copper
6 Solar PV ...7 959. Copper
7 Solar PV ...8 1122. Copper
8 Solar PV ...9 1262. Copper
9 Solar PV ...10 NA Copper
10 Solar PV ...11 923. Copper
# ℹ 232 more rows
# combine the tidied header with the tidied table.
Keep putting everything together
# combine the tidied header with the tidied table. We do this by joining the data by the column namescombined_data <- mineral_info_long |>left_join(sheet_headers_and_col_names, by =join_by(mineral_info_col_names)) |># filter out what were empty columns (where years are NA) filter(!is.na(year)) |># case_when is supercharged if else (like if else except it can take multiple conditions)mutate(unit =case_when( indicator =="Share of clean technologies in total demand"~"Percent",.default ="kiloton" ),# convert the year column from character to numericyear =as.integer(year) ) |>select(mineral_name, indicator, scenario, unit, year, value)combined_data
# A tibble: 209 × 6
mineral_name indicator scenario unit year value
<chr> <chr> <chr> <chr> <int> <dbl>
1 Copper Solar PV Current Year kiloton 2022 682.
2 Copper Solar PV Stated policies scenario kiloton 2025 779.
3 Copper Solar PV Stated policies scenario kiloton 2030 907.
4 Copper Solar PV Stated policies scenario kiloton 2035 925.
5 Copper Solar PV Stated policies scenario kiloton 2040 959.
6 Copper Solar PV Stated policies scenario kiloton 2045 1122.
7 Copper Solar PV Stated policies scenario kiloton 2050 1262.
8 Copper Solar PV Announced pledges scenario kiloton 2025 923.
9 Copper Solar PV Announced pledges scenario kiloton 2030 1177.
10 Copper Solar PV Announced pledges scenario kiloton 2035 1369.
# ℹ 199 more rows
Function to read the data
read_iea_mineral_table <-function(mineral_name_range, mineral_info_range) { mineral_name <-read_key_minerals_sheet(range = mineral_name_range) |>pull() mineral_info <-read_key_minerals_sheet(range = mineral_info_range) mineral_info_col_names <-names(mineral_info) mineral_info_long <- mineral_info |>rename(indicator =`...1`) |>pivot_longer(cols =-indicator,names_to ="mineral_info_col_names") |>add_column(mineral_name) combined_data <- mineral_info_long |>left_join(sheet_headers_and_col_names, by =join_by(mineral_info_col_names)) |># filter out what were empty columns (where years are NA)filter(!is.na(year)) |># case_when is supercharged if elsemutate(unit =case_when( indicator =="Share of clean technologies in total demand"~"Percent",.default ="kiloton" ),# convert the year column from character to numericyear =as.integer(year) ) |>select(mineral_name, indicator, scenario, unit, year, value) combined_data }# bind all data on one filecopper_table <-read_iea_mineral_table(mineral_name_range ="A7",mineral_info_range ="A8:W18")
# A tibble: 779 × 6
mineral_name indicator scenario unit year value
<chr> <chr> <chr> <chr> <int> <dbl>
1 Copper Solar PV Current Year kiloton 2022 682.
2 Copper Solar PV Stated policies scenario kiloton 2025 779.
3 Copper Solar PV Stated policies scenario kiloton 2030 907.
4 Copper Solar PV Stated policies scenario kiloton 2035 925.
5 Copper Solar PV Stated policies scenario kiloton 2040 959.
6 Copper Solar PV Stated policies scenario kiloton 2045 1122.
7 Copper Solar PV Stated policies scenario kiloton 2050 1262.
8 Copper Solar PV Announced pledges scenario kiloton 2025 923.
9 Copper Solar PV Announced pledges scenario kiloton 2030 1177.
10 Copper Solar PV Announced pledges scenario kiloton 2035 1369.
# ℹ 769 more rows
Writing data into folder
write_csv(final_iea_minerals_table,here("data", "iea_total_demand_for_critical_minerals.csv"))# To use cleaned dataour_cleaned_data <-here("data", "iea_total_demand_for_critical_minerals.csv") |>read_csv()
Rows: 779 Columns: 6
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (4): mineral_name, indicator, scenario, unit
dbl (2): year, value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
our_cleaned_data
# A tibble: 779 × 6
mineral_name indicator scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 Copper Solar PV Current Year kiloton 2022 682.
2 Copper Solar PV Stated policies scenario kiloton 2025 779.
3 Copper Solar PV Stated policies scenario kiloton 2030 907.
4 Copper Solar PV Stated policies scenario kiloton 2035 925.
5 Copper Solar PV Stated policies scenario kiloton 2040 959.
6 Copper Solar PV Stated policies scenario kiloton 2045 1122.
7 Copper Solar PV Stated policies scenario kiloton 2050 1262.
8 Copper Solar PV Announced pledges scenario kiloton 2025 923.
9 Copper Solar PV Announced pledges scenario kiloton 2030 1177.
10 Copper Solar PV Announced pledges scenario kiloton 2035 1369.
# ℹ 769 more rows
HW Question
Read in 2.3 EV
read_ev_sheet <-partial(# provide the function, in this case readxl::read_excel().f = read_excel,# provide any arguments you want filled inpath = path_to_sheet,sheet ="2.3 EV",col_names =FALSE)# now all we have to do is provide the rangesheet_header <-read_key_minerals_sheet(range ="A4:W5")
# A tibble: 2 × 23
...1 ...2 ...3 ...4 ...5 ...6 ...7 ...8 ...9 ...10 ...11 ...12 ...13
<lgl> <dbl> <lgl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <lgl> <chr> <dbl> <dbl>
1 NA NA NA State… NA NA NA NA NA NA Anno… NA NA
2 NA 2022 NA 2025 2030 2035 2040 2045 2050 NA 2025 2030 2035
# ℹ 10 more variables: ...14 <dbl>, ...15 <dbl>, ...16 <dbl>, ...17 <lgl>,
# ...18 <chr>, ...19 <dbl>, ...20 <dbl>, ...21 <dbl>, ...22 <dbl>,
# ...23 <dbl>
read_iea_ev_table <-function(mineral_name_range, mineral_info_range) { case_mineral_needs <-read_ev_sheet(range = mineral_name_range) |>pull() mineral_info <-read_ev_sheet(range = mineral_info_range) mineral_info_col_names <-names(mineral_info) mineral_info_long <- mineral_info |>rename(mineral_name =`...1`) |>pivot_longer(cols =-mineral_name,names_to ="mineral_info_col_names") |>add_column(case_mineral_needs) combined_data <- mineral_info_long |>left_join(sheet_headers_and_col_names, by =join_by(mineral_info_col_names)) |># filter out what were empty columns (where years are NA)filter(!is.na(year)) |># case_when is supercharged if elsemutate(unit =case_when( mineral_name =="Total EV"~"kiloton",.default ="kiloton" ),# convert the year column from character to numericyear =as.integer(year) ) |>select(case_mineral_needs, mineral_name, scenario, unit, year, value) combined_data }# bind all data on one fileconstrained_nickel_supply <-read_iea_ev_table(mineral_name_range ="A7",mineral_info_range ="A8:W19")
# A tibble: 1,596 × 6
case_mineral_needs mineral_name scenario unit year value
<chr> <chr> <chr> <chr> <int> <dbl>
1 STEPS - Base case Copper Current Year kilot… 2022 373.
2 STEPS - Base case Copper Stated policies scenario kilot… 2025 580.
3 STEPS - Base case Copper Stated policies scenario kilot… 2030 1044.
4 STEPS - Base case Copper Stated policies scenario kilot… 2035 1219.
5 STEPS - Base case Copper Stated policies scenario kilot… 2040 1421.
6 STEPS - Base case Copper Stated policies scenario kilot… 2045 1458.
7 STEPS - Base case Copper Stated policies scenario kilot… 2050 1346.
8 STEPS - Base case Copper Announced pledges scenario kilot… 2025 689.
9 STEPS - Base case Copper Announced pledges scenario kilot… 2030 1592.
10 STEPS - Base case Copper Announced pledges scenario kilot… 2035 2570.
# ℹ 1,586 more rows
# To use cleaned dataour_cleaned_data_ev <-here("data", "iea_ev_demand_for_minerals.csv") |>read_csv()
Rows: 1596 Columns: 6
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (4): case_mineral_needs, mineral_name, scenario, unit
dbl (2): year, value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
our_cleaned_data_ev
# A tibble: 1,596 × 6
case_mineral_needs mineral_name scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 STEPS - Base case Copper Current Year kilot… 2022 373.
2 STEPS - Base case Copper Stated policies scenario kilot… 2025 580.
3 STEPS - Base case Copper Stated policies scenario kilot… 2030 1044.
4 STEPS - Base case Copper Stated policies scenario kilot… 2035 1219.
5 STEPS - Base case Copper Stated policies scenario kilot… 2040 1421.
6 STEPS - Base case Copper Stated policies scenario kilot… 2045 1458.
7 STEPS - Base case Copper Stated policies scenario kilot… 2050 1346.
8 STEPS - Base case Copper Announced pledges scenario kilot… 2025 689.
9 STEPS - Base case Copper Announced pledges scenario kilot… 2030 1592.
10 STEPS - Base case Copper Announced pledges scenario kilot… 2035 2570.
# ℹ 1,586 more rows
Producing 5 visualizations
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.
# Setting up for graphinglibrary(ggplot2)library(dplyr)library(readr)# Load the datasetour_cleaned_data_ev <-here("data", "iea_ev_demand_for_minerals.csv") |>read_csv()
Rows: 1596 Columns: 6
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (4): case_mineral_needs, mineral_name, scenario, unit
dbl (2): year, value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# A tibble: 266 × 6
# Groups: year [7]
case_mineral_needs mineral_name scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 STEPS - Base case Copper Current Year kilot… 2022 373.
2 STEPS - Base case Copper Stated policies scenario kilot… 2025 580.
3 STEPS - Base case Copper Stated policies scenario kilot… 2030 1044.
4 STEPS - Base case Copper Stated policies scenario kilot… 2035 1219.
5 STEPS - Base case Copper Stated policies scenario kilot… 2040 1421.
6 STEPS - Base case Copper Stated policies scenario kilot… 2045 1458.
7 STEPS - Base case Copper Stated policies scenario kilot… 2050 1346.
8 STEPS - Base case Copper Announced pledges scenario kilot… 2025 689.
9 STEPS - Base case Copper Announced pledges scenario kilot… 2030 1592.
10 STEPS - Base case Copper Announced pledges scenario kilot… 2035 2570.
# ℹ 256 more rows
# A tibble: 266 × 7
# Groups: year [7]
case_mineral_needs mineral_name scenario unit year value total_KT_needed
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 STEPS - Base case Cobalt Current Ye… kilo… 2022 64.6 10802.
2 STEPS - Base case Cobalt Stated pol… kilo… 2025 66.4 NA
3 STEPS - Base case Cobalt Stated pol… kilo… 2030 73.9 NA
4 STEPS - Base case Cobalt Stated pol… kilo… 2035 77.7 NA
5 STEPS - Base case Cobalt Stated pol… kilo… 2040 105. NA
6 STEPS - Base case Cobalt Stated pol… kilo… 2045 134. NA
7 STEPS - Base case Cobalt Stated pol… kilo… 2050 146. NA
8 STEPS - Base case Cobalt Announced … kilo… 2025 77.5 NA
9 STEPS - Base case Cobalt Announced … kilo… 2030 113. NA
10 STEPS - Base case Cobalt Announced … kilo… 2035 159. NA
# ℹ 256 more rows
#esquisser(our_cleaned_data)# Data Visualization 1: Copper demand across different policy scenarios
Visualization 1
ggplot(our_cleaned_data_copper) +aes(x = year,y = value,fill = case_mineral_needs,colour = case_mineral_needs ) +geom_line() +scale_fill_manual(values =c(`Constrained nickel supply`="#F8766D",`Faster uptake of solid state batteries`="#ACA000",`Limited battery size reduction`="#00BB4C",`Lower battery sizes`="#00BAD5",`STEPS - Base case`="#918BFD",`Wider use of silicon-rich anodes`="#FF61C3") ) +scale_color_manual(values =c(`Constrained nickel supply`="#F8766D",`Faster uptake of solid state batteries`="#ACA000",`Limited battery size reduction`="#00BB4C",`Lower battery sizes`="#00BAD5",`STEPS - Base case`="#918BFD",`Wider use of silicon-rich anodes`="#FF61C3") ) +labs(x ="Year",y ="Kilotons",title ="Copper Needs by Year",subtitle ="by Different Case Specific Needs",caption ="Made by Yuhao Shen",color ="Cases" ) +theme_minimal() +facet_wrap(vars(case_mineral_needs))
Visualization 2
# Sorting out copper to total EV demand percentages# Assuming 'Total EV' demand is consistent across the same 'scenario' within 'case_mineral_needs'# and that 'case_mineral_needs' and 'scenario' combinations are unique for 'Copper' and 'Total EV'our_cleaned_data_copper_only <- our_cleaned_data_ev %>%filter(mineral_name =="Copper")our_cleaned_data_copper_only
# A tibble: 133 × 6
case_mineral_needs mineral_name scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 STEPS - Base case Copper Current Year kilot… 2022 373.
2 STEPS - Base case Copper Stated policies scenario kilot… 2025 580.
3 STEPS - Base case Copper Stated policies scenario kilot… 2030 1044.
4 STEPS - Base case Copper Stated policies scenario kilot… 2035 1219.
5 STEPS - Base case Copper Stated policies scenario kilot… 2040 1421.
6 STEPS - Base case Copper Stated policies scenario kilot… 2045 1458.
7 STEPS - Base case Copper Stated policies scenario kilot… 2050 1346.
8 STEPS - Base case Copper Announced pledges scenario kilot… 2025 689.
9 STEPS - Base case Copper Announced pledges scenario kilot… 2030 1592.
10 STEPS - Base case Copper Announced pledges scenario kilot… 2035 2570.
# ℹ 123 more rows
# First, isolate the total EV demand for each scenariototal_ev_demand <- our_cleaned_data_copper %>%filter(mineral_name =="Total EV") %>%select(case_mineral_needs, scenario, year, total_EV = value)# Now merge this data back with the original dataset to get a corresponding total EV value for each rowdata_with_ev <- our_cleaned_data_copper_only %>%left_join(total_ev_demand, by =c("case_mineral_needs", "scenario", "year")) %>%distinct()
Warning in left_join(., total_ev_demand, by = c("case_mineral_needs", "scenario", : Detected an unexpected many-to-many relationship between `x` and `y`.
ℹ Row 1 of `x` matches multiple rows in `y`.
ℹ Row 1 of `y` matches multiple rows in `x`.
ℹ If a many-to-many relationship is expected, set `relationship =
"many-to-many"` to silence this warning.
# Calculate the copper to total EV demand ratiodata_with_ev <- data_with_ev %>%mutate(copper_to_ev_ratio =ifelse(mineral_name =="Copper", value / total_EV *100, NA))# View the modified dataframeprint(data_with_ev)
# A tibble: 114 × 8
case_mineral_needs mineral_name scenario unit year value total_EV
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 STEPS - Base case Copper Current Year kilo… 2022 373. 1480.
2 STEPS - Base case Copper Stated policies s… kilo… 2025 580. 2426.
3 STEPS - Base case Copper Stated policies s… kilo… 2030 1044. 4231.
4 STEPS - Base case Copper Stated policies s… kilo… 2035 1219. 5160.
5 STEPS - Base case Copper Stated policies s… kilo… 2040 1421. 6063.
6 STEPS - Base case Copper Stated policies s… kilo… 2045 1458. 6393.
7 STEPS - Base case Copper Stated policies s… kilo… 2050 1346. 6011.
8 STEPS - Base case Copper Announced pledges… kilo… 2025 689. 2847.
9 STEPS - Base case Copper Announced pledges… kilo… 2030 1592. 6451.
10 STEPS - Base case Copper Announced pledges… kilo… 2035 2570. 10621.
# ℹ 104 more rows
# ℹ 1 more variable: copper_to_ev_ratio <dbl>
ggplot(data_with_ev) +aes(x = year, y = copper_to_ev_ratio, colour = scenario) +geom_point(shape ="circle", size =1.5) +scale_color_hue(direction =1) +labs(y ="Percentage",title ="Copper Demanded As Percentage in EV Market",subtitle ="case specific and by demand",caption ="Made by Yuhao Shen",color ="Scenarios" ) +theme_minimal() +facet_wrap(vars(case_mineral_needs))
# A tibble: 133 × 6
case_mineral_needs mineral_name scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 STEPS - Base case Cobalt Current Year kilot… 2022 64.6
2 STEPS - Base case Cobalt Stated policies scenario kilot… 2025 66.4
3 STEPS - Base case Cobalt Stated policies scenario kilot… 2030 73.9
4 STEPS - Base case Cobalt Stated policies scenario kilot… 2035 77.7
5 STEPS - Base case Cobalt Stated policies scenario kilot… 2040 105.
6 STEPS - Base case Cobalt Stated policies scenario kilot… 2045 134.
7 STEPS - Base case Cobalt Stated policies scenario kilot… 2050 146.
8 STEPS - Base case Cobalt Announced pledges scenario kilot… 2025 77.5
9 STEPS - Base case Cobalt Announced pledges scenario kilot… 2030 113.
10 STEPS - Base case Cobalt Announced pledges scenario kilot… 2035 159.
# ℹ 123 more rows
# First, isolate the total EV demand for each scenariototal_ev_demand_cobalt <- our_cleaned_data_cobalt %>%filter(mineral_name =="Total EV") %>%select(case_mineral_needs, scenario, year, total_EV = value)# Now merge this data back with the original dataset to get a corresponding total EV value for each rowdata_with_ev_co <- our_cleaned_data_cobalt_only %>%left_join(total_ev_demand_cobalt, by =c("case_mineral_needs", "scenario", "year"))
Warning in left_join(., total_ev_demand_cobalt, by = c("case_mineral_needs", : Detected an unexpected many-to-many relationship between `x` and `y`.
ℹ Row 1 of `x` matches multiple rows in `y`.
ℹ Row 1 of `y` matches multiple rows in `x`.
ℹ If a many-to-many relationship is expected, set `relationship =
"many-to-many"` to silence this warning.
# Calculate the copper to total EV demand ratiodata_with_ev_co <- data_with_ev_co %>%distinct() %>%mutate(cobalt_to_ev_ratio =ifelse(mineral_name =="Cobalt", value / total_EV *100, NA)) # View the modified dataframeprint(data_with_ev_co)
# A tibble: 114 × 8
case_mineral_needs mineral_name scenario unit year value total_EV
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 STEPS - Base case Cobalt Current Year kilo… 2022 64.6 1480.
2 STEPS - Base case Cobalt Stated policies s… kilo… 2025 66.4 2426.
3 STEPS - Base case Cobalt Stated policies s… kilo… 2030 73.9 4231.
4 STEPS - Base case Cobalt Stated policies s… kilo… 2035 77.7 5160.
5 STEPS - Base case Cobalt Stated policies s… kilo… 2040 105. 6063.
6 STEPS - Base case Cobalt Stated policies s… kilo… 2045 134. 6393.
7 STEPS - Base case Cobalt Stated policies s… kilo… 2050 146. 6011.
8 STEPS - Base case Cobalt Announced pledges… kilo… 2025 77.5 2847.
9 STEPS - Base case Cobalt Announced pledges… kilo… 2030 113. 6451.
10 STEPS - Base case Cobalt Announced pledges… kilo… 2035 159. 10621.
# ℹ 104 more rows
# ℹ 1 more variable: cobalt_to_ev_ratio <dbl>
ggplot(data_with_ev_co) +aes(x = year, y = cobalt_to_ev_ratio, colour = scenario) +geom_point(shape ="circle", size =1.5) +scale_color_hue(direction =1) +labs(y ="Percentage",title ="Cobalt Demanded As Percentage in EV Market",subtitle ="case specific and by demand",caption ="Made by Yuhao Shen",color ="Scenarios" ) +theme_minimal() +facet_wrap(vars(case_mineral_needs))