The US Geological Survey publishes a list of Strategic Minerals ( https://www.usgs.gov/news/national-news-release/us-geological-survey-releases-2022-list-critical-minerals ). Having a secure supply of these minerals is essential to our security and economic prosperity. However many of these minerals are sourced from outside of the US. This assignment is to develop a reference catalog of the source or sources of each of these minerals and a judgement on the reliability of each source under stressed circumstance (e.g. war, economic crisis, etc.)
Notes:
You will need to identify a source or sources for each of the minerals in the 2022 List of Critical Minerals
You will need to categorize each source country as an ally, a competitor or a neutral party.
You will need to develop data visualizations that tell the story of source dependency and shortfall impact.
This assignment is due at the end of week fourteen of the semester
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ purrr 1.0.2
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 4.0.0 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ 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(ggplot2)library(scales)
Attaching package: 'scales'
The following object is masked from 'package:purrr':
discard
The following object is masked from 'package:readr':
col_factor
library(RColorBrewer)library(gridExtra)
Attaching package: 'gridExtra'
The following object is masked from 'package:dplyr':
combine
# 1. LOAD ALL DATASETS# Dataset 1: Net Import Reliancenet_import <-read.csv("MCS2025_Fig2_Net_Import_Reliance.csv", stringsAsFactors =FALSE)# Dataset 2: Major Import Sources by Countryimport_sources_country <-read.csv("MCS2025_Fig3_Major_Import_Sources.csv",stringsAsFactors =FALSE)# Dataset 3: Critical Minerals Salient Statisticscritical_salient <-read.csv("MCS2025_T5_Critical_Minerals_Salient.csv",stringsAsFactors =FALSE)# Dataset 4: End Use Applicationsend_use <-read.csv("MCS2025_T4_Critical_Minerals_End_Use.csv",stringsAsFactors =FALSE)# Function to parse comma-separated countriesparse_countries <-function(country_string) {if (is.na(country_string) || country_string =="") {return(character(0)) } countries <-str_split(country_string, ",")[[1]] countries <-str_trim(countries)return(countries)}# Create expanded dataset with one row per mineral-country pairmineral_country_pairs <- net_import %>%rowwise() %>%mutate(countries_list =list(parse_countries(Major_Import_Sources_2020_2023)) ) %>%unnest(countries_list) %>%rename(country = countries_list) %>%group_by(Commodity) %>%mutate(import_rank =row_number(), # 1 = primary source, 2 = secondary, etc.import_reliance_numeric =case_when( Net_Import_Reliance_pct_2024 =="100"~100, Net_Import_Reliance_pct_2024 ==">95"~97.5, Net_Import_Reliance_pct_2024 ==">75"~80, Net_Import_Reliance_pct_2024 ==">50"~60, Net_Import_Reliance_pct_2024 =="<50"~40, Net_Import_Reliance_pct_2024 =="<25"~20, Net_Import_Reliance_pct_2024 =="E"~NA_real_,TRUE~as.numeric(Net_Import_Reliance_pct_2024) ) ) %>%ungroup()
Warning: There were 15 warnings in `mutate()`.
The first warning was:
ℹ In argument: `import_reliance_numeric = case_when(...)`.
ℹ In group 1: `Commodity = "ABRASIVES, fused aluminum oxide"`.
Caused by warning:
! NAs introduced by coercion
ℹ Run `dplyr::last_dplyr_warnings()` to see the 14 remaining warnings.
# STEP 1: CLEAN DATA - FILTER TO CRITICAL MINERALS ONLY# List of critical minerals to keep (based on 2025 list)critical_minerals_keep <-c("ALUMINUM","ALUMINA","ANTIMONY, metal and oxide","ARSENIC, all forms","BARITE","BISMUTH, metal, alloys, and scrap","CESIUM","CHROMIUM, all forms ","COBALT, metal, oxides, and salts","FLUORSPAR","GALLIUM, metal","GERMANIUM","GRAPHITE (NATURAL)","INDIUM","LITHIUM","MAGNESIUM COMPOUNDS","MAGNESIUM METAL","MANGANESE","NICKEL","NIOBIUM (COLUMBIUM)","PALLADIUM","PLATINUM","RARE EARTHS, compounds and metals","RUBIDIUM","SCANDIUM","TANTALUM","TELLURIUM","TIN, refined","TITANIUM MINERAL CONCENTRATES","TITANIUM, sponge metal","TUNGSTEN","VANADIUM","YTTRIUM, compounds","ZINC, refined","ZIRCONIUM, ores and concentrates")# Filter to critical minerals onlynet_import <- net_import %>%filter(Commodity %in% critical_minerals_keep)mineral_country_pairs <- mineral_country_pairs %>%filter(Commodity %in% critical_minerals_keep)cat("Filtered to", length(unique(net_import$Commodity)), "critical minerals\n\n")
# PLOT 4 China Dependency WITH Applications# Shows import reliance AND what each mineral is used for# Get China-dependent mineralschina_minerals <- mineral_country_pairs %>%filter(country =="China"| country =="China3") %>%filter(import_rank ==1) %>%select(Commodity_clean, import_reliance_numeric) %>%distinct() %>%arrange(desc(import_reliance_numeric)) %>%head(15)# Add applications from end_usechina_with_apps <- china_minerals %>%left_join( end_use %>%select(Critical.Mineral, Primary.Applications),by =c("Commodity_clean"="Critical.Mineral") ) %>%mutate(Applications =case_when(!is.na(Primary.Applications) ~ Primary.Applications, Commodity_clean =="Rare Earths"~"Batteries, magnets, defense", Commodity_clean =="Magnesium"~"Metallurgy, alloys", Commodity_clean =="Yttrium"~"Phosphors, lasers",TRUE~"Multiple uses" ),# Shorten applications for displayApps_short =case_when(str_length(Applications) >35~paste0(str_sub(Applications, 1, 32), "..."),TRUE~ Applications ),Commodity_clean =fct_reorder(Commodity_clean, import_reliance_numeric) )# Create plot with applications labeledplot4_with_apps <-ggplot(china_with_apps,aes(x = Commodity_clean, y = import_reliance_numeric)) +geom_col(width =0.7, fill ="#fee5d9") +# Add percentage labelsgeom_text(aes(label =paste0(round(import_reliance_numeric, 0), "%")), hjust =1.1, size =3.5, fontface ="bold", color ="black") +# Add application labels OUTSIDE the barsgeom_text(aes(label = Apps_short, y =0), hjust =-0.05, size =3, color ="gray30") +coord_flip() +scale_y_continuous(labels =percent_format(scale =1),limits =c(0, 105), # Extended to make room for labelsexpand =c(0, 0)) +labs(title ="U.S. Dependency on China as Primary Source",subtitle ="Import reliance and primary applications for each mineral",x =NULL,y ="U.S. Import Reliance" ) +theme_minimal(base_size =13) +theme(plot.title =element_text(face ="bold", size =15, hjust =0.5, margin =margin(b =5)),plot.subtitle =element_text(size =11, hjust =0.5, margin =margin(b =20)),panel.grid.major.y =element_blank(),panel.grid.minor =element_blank(),axis.text.y =element_text(size =11),axis.title.x =element_text(size =12) )print(plot4_with_apps)
I have examined 35 critical minerals(which is only half of the critical minerals) and found serious problems with America’s supply chains. We’re completely dependent on imports for 15 of these minerals, and China is our main supplier for most of them. This is a big problem because these aren’t just random materials, they’re essential for our military equipment, computer chips, batteries, and advanced technology.