Background

Critical minerals are vital to the United States’ national security, economic strength, and technological advancement. According to the U.S. Geological Survey (USGS), these minerals are key inputs for defense systems, clean-energy technologies, electronics, and advanced manufacturing. Many of the minerals on the 2022 USGS Critical Minerals List, however, are produced primarily outside the United States, often in countries with uncertain or adversarial geopolitical relationships.

Global production of many critical minerals is highly concentrated, sometimes dominated by a single country or small group of countries. This concentration creates vulnerabilities if supply chains are disrupted by geopolitical conflict, trade restrictions, economic instability, or natural disasters. Understanding where these minerals are produced, and how reliable those sources are during periods of stress, is essential for evaluating national-security risks and strengthening supply-chain resilience.

This project builds a reference catalog of the primary source countries for each mineral on the 2022 USGS Critical Minerals List and classifies those countries as allies, competitors, or neutral parties. By combining production data with geopolitical context, the analysis highlights U.S. supply dependencies and identifies minerals that pose the greatest strategic risk.

Research Analysis

This analysis examines the supply chains of critical minerals essential to the United States, focusing on the countries that produce these minerals. By mapping each mineral to its primary source countries and categorizing those countries as allies, competitors, or neutral parties, the study highlights areas of strategic dependency. The analysis aims to quantify potential vulnerabilities and provide a reference framework for understanding geopolitical and economic risks associated with mineral supply.This analysis will:

Data for this analysis will come from the U.S. Geological Survey Minerals Yearbook Data for Select Mineral Commodities Referenced in the U.S. Geological Survey Methodology and Technical Input for the 2025 U.S.

https://www.sciencebase.gov/catalog/item/6899fa60d4be02504d348b4f

Research Question

Which critical minerals on the 2022 USGS list are most vulnerable to supply disruption based on their source countries, and how does geopolitical alignment (ally, competitor, neutral) affect the reliability of these mineral supplies for the United States?

Hypothesis

Critical minerals that are primarily sourced from competitor or neutral countries with concentrated production are at higher risk of supply disruption, making the United States more vulnerable to strategic and economic risks.

production <- read.csv("C:\\Users\\Kesha\\Desktop\\Fall 2025\\Data 608\\USGS_MYB_CML-Data_Production_2025-08-22.csv", stringsAsFactors = FALSE)
capacity   <- read.csv("C:\\Users\\Kesha\\Desktop\\Fall 2025\\Data 608\\USGS_MYB_CML-Data_Capacity_2025-08-22.csv", stringsAsFactors = FALSE)
consumption <- read.csv("C:\\Users\\Kesha\\Desktop\\Fall 2025\\Data 608\\USGS_MYB_CML-Data_Consumption_2025-08-22.csv", stringsAsFactors = FALSE)

colnames(production)
##  [1] "COMMODITY"       "COMMODITY_FORM"  "COUNTRY"         "STATISTIC"      
##  [5] "YEAR"            "QUANTITY"        "UNITS"           "STATISTIC_NOTES"
##  [9] "DATA_SOURCE"     "TABLE_NOTES"
colnames(capacity)
##  [1] "COMMODITY"         "COMMODITY_FORM"    "COUNTRY"          
##  [4] "COUNTRY_NOTES"     "OPERATOR"          "OPERATOR_LOCATION"
##  [7] "FACILITY_TYPE"     "STATISTIC"         "YEAR"             
## [10] "QUANTITY"          "UNITS"             "STATISTIC_NOTES"  
## [13] "DATA_SOURCE"       "TABLE_NOTES"
colnames(consumption)
##  [1] "COMMODITY"        "COMMODITY_FORM"   "FORM_NOTES"       "COUNTRY"         
##  [5] "END_USE_CATEGORY" "END_USE_NOTES"    "STATISTIC"        "YEAR"            
##  [9] "QUANTITY"         "UNITS"            "STATISTIC_NOTES"  "DATA_SOURCE"     
## [13] "TABLE_NOTES"
production$QUANTITY <- gsub(",", "", production$QUANTITY)
production$QUANTITY <- gsub("<", "", production$QUANTITY)
production$QUANTITY <- as.numeric(production$QUANTITY)
## Warning: NAs introduced by coercion
production$COUNTRY <- stri_encode(production$COUNTRY, from = "latin1", to = "UTF-8")
consumption$QUANTITY <- gsub(",", "", consumption$QUANTITY)
consumption$QUANTITY <- as.numeric(consumption$QUANTITY)
## Warning: NAs introduced by coercion
prod <- production %>%
  dplyr::select(COMMODITY, COUNTRY, YEAR, QUANTITY) %>%
  rename(Production = QUANTITY)

cap <- capacity %>%
  dplyr::select(COMMODITY, COUNTRY, YEAR, QUANTITY) %>%
  rename(Capacity = QUANTITY)

cons <- consumption %>%
  dplyr::select(COMMODITY, COUNTRY, YEAR, QUANTITY) %>%
  rename(Consumption = QUANTITY)

# Merge 
usgs_full <- prod %>%
  full_join(cap, by = c("COMMODITY", "COUNTRY", "YEAR")) %>%
  full_join(cons, by = c("COMMODITY", "COUNTRY", "YEAR"))
## Warning in full_join(., cap, by = c("COMMODITY", "COUNTRY", "YEAR")): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 199 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.
## Warning in full_join(., cons, by = c("COMMODITY", "COUNTRY", "YEAR")): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 221 of `x` matches multiple rows in `y`.
## ℹ Row 21 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
##   "many-to-many"` to silence this warning.
usgs_full[is.na(usgs_full)] <- 0

Let start by looking at how much the US actually consumes of each mineral

#Summarize US consumption

us_consumption <- consumption %>%
  filter(COUNTRY == "United States") %>%
  mutate(QUANTITY = as.numeric(gsub(",", "", QUANTITY))) %>%
  group_by(COMMODITY) %>%
  summarise(Total_Consumption = sum(QUANTITY, na.rm = TRUE)) %>%
  arrange(desc(Total_Consumption))

# top consumers
us_consumption %>%
  mutate(
    COMMODITY = reorder(COMMODITY, Total_Consumption),
    highlight = Total_Consumption %in% sort(Total_Consumption, decreasing = TRUE)[1:3]
  ) %>%
  ggplot(aes(x = COMMODITY, y = Total_Consumption, fill = highlight)) +
  
  geom_col(width = 0.75) +   
  coord_flip() +             
  
  # top 3
  scale_fill_manual(
    values = c("FALSE" = "grey70", "TRUE" = "#08306B"),
    guide = "none"
  ) +
  
  scale_y_log10(
    labels = comma,
    breaks = trans_breaks("log10", function(x) 10^x)
  ) +
  
  # Median 
  geom_hline(
    yintercept = median(us_consumption$Total_Consumption),
    linetype = "dashed",
    color = "grey40"
  ) +
  
  annotate(
    "text",
    y = median(us_consumption$Total_Consumption),
    x = 1,
    label = "Median consumption",
    hjust = 0,
    vjust = -0.5,
    size = 3.5,
    color = "grey40"
  ) +
  
  # Label top 3 
  geom_text(
    data = . %>% filter(highlight),
    aes(label = comma(Total_Consumption), y = Total_Consumption),
    hjust = -0.1,  
    size = 3.5,
    fontface = "bold",
    color = "#08306B"
  ) +
  
  labs(
    title = "The U.S. Economy Relies Disproportionately on a Small Set of Critical Minerals,\nIncreasing Exposure to Supply Chain Disruptions",
    subtitle = "A small number of minerals dominate U.S. consumption, meaning disruptions to their supply would have outsized\neconomic and strategic consequences",
    x = "",
    y = "Total Consumption (tons, log scale)",
    caption = "Consumption volumes are presented on a logarithmic scale to capture the extreme skew in demand. The dominance of a few minerals underscores the strategic importance of assessing source-country reliability."
  ) +
  
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(size = 20, face = "bold"),
    plot.subtitle = element_text(size = 14, margin = margin(b = 12)),
    axis.text.y = element_text(face = "bold"),
    panel.grid.major.y = element_blank(),
    panel.grid.minor = element_blank()
  )

Who are the top producers per mineral in the world, and where does the US stand?

# top 3 producers per mineral
top3_prod <- production %>%
  filter(YEAR == 2023, STATISTIC == "Production", COUNTRY != "World", COMMODITY != "Helium") %>%
  mutate(QUANTITY = as.numeric(gsub(",", "", QUANTITY)),
    COUNTRY = case_when(
      COUNTRY == "United States" ~ "U.S.",
      COUNTRY == "Korea, Republic of" ~ "Korea",
      COUNTRY == "Congo (Kinshasa)" ~ "Congo",
      TRUE ~ COUNTRY
    )) %>%
  group_by(COMMODITY, COUNTRY) %>%
  summarise(Total_Production = sum(QUANTITY, na.rm = TRUE), .groups = "drop") %>%
  group_by(COMMODITY) %>%
  mutate(
    rank = dense_rank(desc(Total_Production)),
    total_mineral = sum(Total_Production),
    pct = Total_Production / total_mineral * 100
  ) %>%
  filter(rank <= 3) %>%  
  ungroup() %>%
  mutate(
 color_group = case_when(
    COUNTRY == "U.S." ~ "U.S. in top 3",
    rank == 1 ~ "Top Producer",
    rank == 2 ~ "Second Highest Producer",
    rank == 3 ~ "Third Highest Producer"
    ),
    label_color = case_when(
      color_group %in% c("Top Producer", "U.S. in top 3") ~ "white", 
      TRUE ~ "black"
    )
  )

color_map <- c(
  "Top Producer" = "#08306B",       
  "Second Highest Producer" = "#4292C6",      
  "Third Highest Producer" = "#C6DBEF",     
  "U.S. in top 3" = "darkred"     
)


ggplot(top3_prod, aes(x = reorder(COMMODITY, Total_Production, sum),
                      y = Total_Production,
                      fill = color_group)) +
  geom_col(color = "white", width = 0.75) +
  geom_text(aes(label = paste0(COUNTRY, " (", round(pct, 1), "%)"),
                color = label_color),
            position = position_stack(vjust = 0.5),
            size = 3.5,        
            fontface = "bold") +  
  scale_color_identity() + 
  coord_flip() +
  scale_y_log10(labels = comma) +
  scale_fill_manual(values = color_map, name = "Producer") +
  labs(
    title = "Who Controls the World's Minerals? A Look at the Top 3 Producing Countries for Critical Resources",
subtitle = "Global production is highly concentrated: a handful of nations dominate extraction across nearly every critical mineral.\nThe U.S. ranks among the top 3 producers for only 5 minerals, while China leads production for several key minerals.",
x = "",
y = "Annual Production (log scale, tons)",
caption = "Data show how global supply chains, and geopolitical leverage, hinge on a few top producers for each mineral. The U.S. is the third-highest producer\nof Molybdenum, its top-consumed mineral, while China is the top producer of Vanadium, the second-highest consumed mineral by the U.S.") +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 18),
    plot.subtitle = element_text(size = 14),
    plot.caption = element_text(face = "italic", size = 11, color = "grey10"),
    legend.position = "right",
    axis.text.y = element_text(face = "bold"),
    panel.grid.major.y = element_blank(),
    panel.grid.minor = element_blank()
  )

How many of these minerals are dominant by competitors, allies, or neutral parties?

ally_countries <- c(
  # NATO + EU allies
  "Albania", "Belgium", "Bulgaria", "Canada", "Croatia", "Czechia", "Denmark", "Estonia",
  "Finland", "France", "Germany", "Greece", "Hungary", "Iceland", "Italy", "Latvia",
  "Lithuania", "Luxembourg", "Montenegro", "Netherlands", "Norway", "North Macedonia",
  "Slovakia", "Slovenia", "Spain", "Turkey", "United Kingdom",
  # Indo-Pacific allies
  "Australia", "Japan", "Korea, Republic of", "Philippines", "Thailand", "New Zealand",
  # MNNA + key partners
  "Argentina", "Bahrain", "Brazil", "Colombia", "Egypt", "Israel", "Jordan", "Kuwait",
  "Morocco", "Pakistan", "Qatar", "Tunisia", "Singapore", "Taiwan", "Ukraine", "Georgia",
  "Sweden", "Saudi Arabia", "United Arab Emirates"
)

competitor_countries <- c(
  "China", "Russia", "Iran", "Korea, North", "Cuba", "Venezuela", "Syria", "Belarus", 
  "Myanmar", "Nicaragua"
)


production <- production %>%
  mutate(
    Category = case_when(
      COUNTRY %in% ally_countries ~ "Ally",
      COUNTRY %in% competitor_countries ~ "Competitor",
      TRUE ~ "Neutral"
    ),
    QUANTITY = as.numeric(gsub(",", "", QUANTITY))  
  )

dependency <- production %>%
  group_by(COMMODITY, Category) %>%
  summarise(Total_Production = sum(QUANTITY, na.rm = TRUE), .groups = "drop") %>%
  group_by(COMMODITY) %>%
  mutate(
    Total_Prod = sum(Total_Production),
    Category_Share = Total_Production / Total_Prod
  ) %>%
  ungroup()

# Compute
category_shares <- dependency %>%
  select(COMMODITY, Category, Category_Share) %>%
  pivot_wider(
    names_from = Category,
    values_from = Category_Share,
    values_fill = 0
  ) %>%
  rename(
    Ally_Share = Ally,
    Competitor_Share = Competitor,
    Neutral_Share = Neutral
  )

# Join
dependency <- dependency %>%
  left_join(category_shares, by = "COMMODITY") %>%
  mutate(
    Annotate = ifelse(Competitor_Share > Ally_Share & Category == "Competitor",
                      "Competitor > Ally", NA)
  )

p1 <- ggplot(dependency, aes(
  x = reorder(COMMODITY, -Competitor_Share),
  y = Total_Production,
  fill = Category,
  text = paste0(
    "Mineral: ", COMMODITY, "<br>",
    "Ally: ", round(Ally_Share*100,1), "%<br>",
    "Competitor: ", round(Competitor_Share*100,1), "%<br>",
    "Neutral: ", round(Neutral_Share*100,1), "%<br>",
    "Category Production: ", scales::comma(Total_Production), "<br>",
    "Flag: ", ifelse(Category == "Competitor" & Competitor_Share > Ally_Share,
                     paste0(round(Competitor_Share*100,1), "% Competitor > Ally"), NA)
  )
)) +
  geom_col(width = 0.75, color = "white") +
  coord_flip() +
  scale_fill_manual(values = c(
    "Ally" = "#08306B",
    "Competitor" = "darkred",
    "Neutral" = "#BDC3C7"
  )) +
  scale_y_log10(labels = scales::comma) +
  labs(
    title = "When Allies Can't Deliver: Competitors Dominate Mineral Production",
    x = "",
    y = "Production (log scale)",
    fill = ""
  ) +
  theme_minimal(base_size = 12)



subtitle_text <- paste(
  "Although the U.S. has allied nations producing critical minerals,",
  "most production is controlled by competitors or neutral countries.",  
  "\nThis leaves the U.S. vulnerable to supply disruptions, forcing potential reliance",
  "on nations with conflicting strategic interests."
)

ggplotly(p1, tooltip = "text", width = 1500, height = 900) %>%
  layout(
     margin = list(t = 100),
    title = list(
      text = paste0("<b>When Allies Can't Deliver: Competitors Dominate Mineral Production</b><br>",
                    "<sup>", subtitle_text, "</sup>"),
      x = 0.05,
      xanchor = "left"
    ))

Are Critical Minerals at risk? Conclusion: Production vs. Consumption for U.S

# global production per mineral

prod_summary <- production %>%
  mutate(QUANTITY = as.numeric(gsub(",", "", QUANTITY))) %>%
  group_by(COMMODITY, Category) %>%
  summarise(Total_Production = sum(QUANTITY, na.rm = TRUE), .groups = "drop") %>%
  group_by(COMMODITY) %>%
  mutate(Competitor_Share = Total_Production[Category == "Competitor"] / sum(Total_Production)) %>%
  ungroup()

total_prod <- prod_summary %>%
  group_by(COMMODITY) %>%
  summarise(
    Total_Production = sum(Total_Production),
    Competitor_Share = max(Competitor_Share, na.rm = TRUE)
  )

# U.S. consumption per mineral

us_consumption <- consumption %>%
  filter(COUNTRY == "United States") %>%
  mutate(QUANTITY = as.numeric(gsub(",", "", QUANTITY))) %>%
  group_by(COMMODITY) %>%
  summarise(Total_Consumption = sum(QUANTITY, na.rm = TRUE))


risk_df <- total_prod %>%
  left_join(us_consumption, by = "COMMODITY") %>%
  mutate(
    Total_Consumption = ifelse(is.na(Total_Consumption), 0, Total_Consumption),
    Dependency_Risk = Total_Consumption > Total_Production
  )

p <- ggplot(risk_df, aes(x = Total_Production, y = Total_Consumption, label = COMMODITY)) +
  geom_point(aes(color = Dependency_Risk, size = Competitor_Share), alpha = 0.8) +
  geom_text(vjust = -0.7, size = 3.5, fontface = "bold") +
  geom_abline(intercept = 0, slope = 1, linetype = "dashed", color = "red") +
  scale_x_log10(labels = scales::comma) +
  scale_y_log10(labels = scales::comma) +
  scale_color_manual(values = c("FALSE" = "#2E8B57", "TRUE" = "#E74C3C")) +
  scale_size_continuous(range = c(3, 8), name = "Competitor Share") +
  theme_minimal(base_size = 12) +
  labs(
    x = "Global Production (log scale, tons)",
    y = "U.S. Consumption (log scale, tons)",
    color = ""
  )

subtitle_text <- "Red points indicate minerals where U.S. consumption exceeds global production (extreme risk). Point size shows competitor dominance, highlighting geopolitical risk\nfor Molybdenum, Vanadium, Bismuth, Zinc, and Aluminum"

ggplotly(p, tooltip = c("label", "x", "y", "size", "color"), width = 1500, height = 900) %>%
  layout(
    title = list(
      text = paste0(
        "<b>U.S. Faces Strategic Mineral Supply Gaps: Consumption Outpaces Global Production with High Competitor Control</b><br>",
        "<sup>", subtitle_text, "</sup><br>"
      ),
      x = 0.05,
      xanchor = "left"
    ),
    margin = list(t = 120)  
  )
## Warning in scale_y_log10(labels = scales::comma): log-10 transformation introduced infinite values.
## log-10 transformation introduced infinite values.

Conclusion

The United States faces significant vulnerabilities in its critical mineral supply chains. Analysis shows that for several key minerals—including Molybdenum, Vanadium, Bismuth, Zinc, and Barite—U.S. consumption alone exceeds total global production. These “extreme risk” cases highlight the potential for severe supply shortages if global production is disrupted, even temporarily. At the same time, global production is highly concentrated, with many minerals controlled primarily by competitor nations such as China and Russia, increasing the likelihood that geopolitical tensions could exacerbate supply risks.

Domestic and allied production is limited, and the U.S. ranks among the top three producers for only a handful of minerals. This dependency, coupled with concentrated competitor control, underscores the strategic importance of diversifying supply sources, strengthening domestic production capacity, and building international partnerships. Without proactive measures, the U.S. remains exposed to economic and national security risks stemming from overreliance on foreign sources of critical minerals.