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 ="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>
4.4.4.2 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
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
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
# A tibble: 228 × 6
mineral_name indicator scenario unit year value
<chr> <chr> <chr> <chr> <int> <dbl>
1 Copper Constrained nickel supply Current Year kilo… 2022 NA
2 Copper Constrained nickel supply Stated policies sce… kilo… 2025 NA
3 Copper Constrained nickel supply Stated policies sce… kilo… 2030 NA
4 Copper Constrained nickel supply Stated policies sce… kilo… 2035 NA
5 Copper Constrained nickel supply Stated policies sce… kilo… 2040 NA
6 Copper Constrained nickel supply Stated policies sce… kilo… 2045 NA
7 Copper Constrained nickel supply Stated policies sce… kilo… 2050 NA
8 Copper Constrained nickel supply Announced pledges s… kilo… 2025 NA
9 Copper Constrained nickel supply Announced pledges s… kilo… 2030 NA
10 Copper Constrained nickel supply Announced pledges s… kilo… 2035 NA
# ℹ 218 more rows
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 }
Rows: 1368 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.
# Prep Copper data for scenarios under constrained nickel supply for copper vs currentcopper_data<-our_cleaned_data|>filter(indicator=="Copper", mineral_name=="Constrained nickel supply")copper_data
# Visualization 1:ggplot(copper_data, aes(x = year, y = value, color = scenario, group = scenario)) +geom_line() +geom_point() +facet_wrap(~indicator, scales ='free_y') +labs(title ="Demand for Copper Over Time by Scenario",x ="Year",y ="Demand (kilotons)",color ="Scenario") +theme_minimal()
#The chart to show the projected demand for copper over time, segmented by different policy scenarios. It indicates a significant increase in demand across all scenarios, with the "Net Zero Emissions by 2050" scenario showing the steepest rise.
Insight 2
# Plot for Cobalt demand under different scenarios vs current# Visualization 2: Line Plot of Copper and Cobalt Demand Over Time cobalt_data<-our_cleaned_data|>filter(indicator=="Cobalt",mineral_name=="Constrained nickel supply")cobalt_data
ggplot(cobalt_data, aes(x = year, y = value, color = scenario, group = scenario)) +geom_line() +geom_point() +facet_wrap(~indicator, scales ='free_y') +labs(title ="Demand for Cobalt Over Time by Scenario",x ="Year",y ="Demand (kilotons)",color ="Scenario") +theme_minimal()
#The chart illustrates the projected demand for cobalt over time, delineated by different policy scenarios. It shows an initial dip in demand under the "Stated policies scenario," followed by a recovery and eventual surpassing of the "Current Year" demand in the "Net Zero Emissions by 2050" scenario, indicating a rebound and growth in demand for cobalt in the context of aggressive environmental goals.
Insight 3
library(dplyr)#Filter for Copper and Cobalt for scenario where theres a faster uptake of solid state batteriescopper_faster <- our_cleaned_data|>filter(indicator =="Copper"& mineral_name =="Faster uptake of solid state batteries")cobalt_faster <- our_cleaned_data |>filter(indicator =="Cobalt"& mineral_name =="Faster uptake of solid state batteries")# Joining the two data frames# Assuming you want to join by 'year' and 'scenario' which are common columnscombined_faster <-full_join(copper_faster, cobalt_faster, by =c("year", "scenario"), suffix =c("_copper", "_cobalt"))# Now combined_faster contains both Copper and Cobalt data for Net zero scenariocombined_faster_netzero<-combined_faster|>filter(scenario=="Net Zero Emissions by 2050 scenario")# If you want to add Cobalt data to the same plot, you could add another geom_line() for cobalt, e.g.,ggplot(combined_faster_netzero, aes(x = year)) +geom_smooth(aes(y = value_copper, color ="Copper"), method ='loess') +geom_smooth(aes(y = value_cobalt, color ="Cobalt"), method ='loess') +labs(title ="Trend of Copper and Cobalt Demand if there's faster uptake of solid state batteries",x ="Year",y ="Demand (kilotons)") +scale_color_manual(values =c("Copper"="blue", "Cobalt"="red")) +theme_minimal()
`geom_smooth()` using formula = 'y ~ x'
`geom_smooth()` using formula = 'y ~ x'
Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
-Inf
Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
-Inf
#This chart compares the demand trends for copper and cobalt under the assumption of a faster uptake of solid-state batteries. The steep increase and plateau in copper demand suggest a significant reliance and leveling off in the technology's maturation, while the relatively flat line for cobalt indicates a lower impact on its demand, possibly due to alternative technologies reducing cobalt usage
Insight 4
# Assuming df is your cleaned dataframe# Filter the data for the current yearcurrent_year <- our_cleaned_data |>filter(scenario =="Current Year")# Further filter the data for 'Constrained nickel supply'current_year_filtered <- current_year |>filter(mineral_name =="Constrained nickel supply")current_year_base <- current_year_filtered |>filter(indicator !="Total EV")current_year_base
# A tibble: 22 × 6
mineral_name indicator scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 Constrained nickel supply Copper Current Year kiloton 2022 381.
2 Constrained nickel supply Cobalt Current Year kiloton 2022 63.5
3 Constrained nickel supply Graphite Current Year kiloton 2022 557.
4 Constrained nickel supply Lithium Current Year kiloton 2022 69.6
5 Constrained nickel supply Manganese Current Year kiloton 2022 74.5
6 Constrained nickel supply Nickel Current Year kiloton 2022 313.
7 Constrained nickel supply Silicon Current Year kiloton 2022 8.70
8 Constrained nickel supply Neodymium Current Year kiloton 2022 3.96
9 Constrained nickel supply Dysprosium Current Year kiloton 2022 0.413
10 Constrained nickel supply Praseodymium Current Year kiloton 2022 0.594
# ℹ 12 more rows
# A tibble: 1 × 6
mineral_name indicator scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 Constrained nickel supply Total EV Current Year kiloton 2022 1473.
# Calculate the total value for 'Total EV'total_ev_value <-sum(total_ev$value)# Calculate the indicator share of EVindicator_share_of_ev <- current_year_base |>mutate(share_of_ev = value / total_ev_value)indicator_share_of_ev
#Graphing # Ordering Bars in Bar Graphindicator_share_of_ev_ordered <- indicator_share_of_ev |>arrange(desc(share_of_ev))# Flip the Bar Graph to Horizontalggplot(indicator_share_of_ev_ordered, aes(x =reorder(indicator, share_of_ev), y = share_of_ev, fill = indicator)) +geom_bar(stat ="identity", position ="dodge") +coord_flip() +labs(title ="Mineral Demand Share for EV under Constrained Nickle Supply Scenraio", x ="Indicator", y ="Share of EV Demand") +theme_minimal()
#Thebar chart displays the share of each mineral's demand in the production of electric vehicles (EV) under a constrained nickel supply scenario. The length of each bar represents the proportion of demand for that particular mineral. The chart highlights which minerals may see increased demand relative to others when nickel supply is limited, guiding strategic decisions in supply chain management and investment within the EV industry.
Insight 4
::: {.cell}
```{.r .cell-code}
library(dplyr)
# Filter the data for the Net zero target
scenario_2050 <-our_cleaned_data |>
filter(scenario =="Net Zero Emissions by 2050 scenario")
# Further filter the data for 'Wider use of silicon-rich anodes'
scenario2050_filtered <-scenario_2050|>
filter(mineral_name == "Wider use of silicon-rich anodes")
current_year_base <- current_year_filtered |>
filter(indicator != "Total EV")
current_year_base
# A tibble: 22 × 6
mineral_name indicator scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 Constrained nickel supply Copper Current Year kiloton 2022 381.
2 Constrained nickel supply Cobalt Current Year kiloton 2022 63.5
3 Constrained nickel supply Graphite Current Year kiloton 2022 557.
4 Constrained nickel supply Lithium Current Year kiloton 2022 69.6
5 Constrained nickel supply Manganese Current Year kiloton 2022 74.5
6 Constrained nickel supply Nickel Current Year kiloton 2022 313.
7 Constrained nickel supply Silicon Current Year kiloton 2022 8.70
8 Constrained nickel supply Neodymium Current Year kiloton 2022 3.96
9 Constrained nickel supply Dysprosium Current Year kiloton 2022 0.413
10 Constrained nickel supply Praseodymium Current Year kiloton 2022 0.594
# ℹ 12 more rows
# A tibble: 1 × 6
mineral_name indicator scenario unit year value
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 Constrained nickel supply Total EV Current Year kiloton 2022 1473.
# Calculate the total value for 'Total EV'total_ev_value <-sum(total_ev$value)# Calculate the indicator share of EVindicator_share_of_ev <- current_year_base |>mutate(share_of_ev = value / total_ev_value)indicator_share_of_ev
ggplot(indicator_share_of_ev, aes(x ='', y = share_of_ev, fill=indicator)) +geom_bar(stat ='identity', width =1) +coord_polar('y', start =0) +labs(title ='Mineral Share of EV for Silicon-rich Anodes in 2050 Net Zero Scenario', x ='', y ='', fill ='Mineral Name') +theme_void()
#The pie chart represents the distribution of various minerals used for silicon-rich anodes in electric vehicles (EV) in the 2050 Net Zero Emissions scenario. It visually breaks down the relative demand for each mineral, with larger pie slices indicating a higher demand, and thus highlighting critical minerals for future EV technology