SU
June 18, 2025
April 15, 2026
---
title: "data fluoride map - g"
author: "SU"
date: 2025-06-18
date-modified: last-modified
language:
title-block-published: "CREATED"
title-block-modified: "UPDATED"
format:
html:
toc: true
toc-expand: 3
code-fold: true
code-tools: true
editor: visual
execute:
echo: false
cache: true
warning: false
message: false
---
# Packages
```{r}
pacman::p_load(tidyverse,
tidygeocoder,
sf,
here,
readxl,
leaflet)
```
# Dataset
```{r}
df <- readxl::read_excel(here("data_map", "Paraugi.xlsx"))
```
```{r}
# 1. Clean the Data & Extract City Names
clean_df <- df %>%
mutate(
# Use regular expressions to extract everything from the start up to the first comma
Location_Clean = str_extract(`City/region`, "^[^,]+"),
# Append the country to ensure the geocoder finds the exact right locations
Search_Query = paste0(Location_Clean, ", Latvia")
)
```
```{r}
# 2. Geocode the Locations (Convert text to Lat/Lon)
geocoded_df <- clean_df %>%
geocode(address = Search_Query, method = 'osm', lat = latitude, long = longitude)
```
```{r}
# 3. Convert to a Spatial Object (sf)
# Drop any rows where geocoding failed (latitude is NA) before converting
spatial_df <- geocoded_df %>%
filter(!is.na(latitude)) %>%
st_as_sf(coords = c("longitude", "latitude"), crs = 4326)
```
```{r}
# 4. Build the Interactive Map
leaflet(spatial_df) %>%
# Add a clean, unobtrusive basemap (CartoDB Positron is great for data visualization)
addProviderTiles(providers$CartoDB.Positron) %>%
# Add points scaled by Fluoride concentration
addCircleMarkers(
radius = ~`F-concentration ppm` * 25, # Multiply to make the differences visually apparent
color = "#2c7fb8", # A professional blue hex code
stroke = FALSE,
fillOpacity = 0.7,
# Create an HTML popup that shows the data when a user clicks a point
popup = ~paste(
"<strong>Location:</strong>", Location_Clean, "<br>",
"<strong>Raw Data String:</strong>", `City/region`, "<br>",
"<strong>F-concentration:</strong>", `F-concentration ppm`, "ppm"
)
)
```
# Static map
```{r}
pacman::p_load(
tidyverse,
tidygeocoder,
sf,
rnaturalearth,
viridis,
giscoR, # for the choropleth
ggspatial
)
```
```{r}
# Convert to an sf object for the point layer, keeping raw coords
spatial_df <- geocoded_df %>%
filter(!is.na(latitude)) %>%
st_as_sf(coords = c("longitude", "latitude"), crs = 4326, remove = FALSE)
```
```{r}
# 2. Fetch the Base Map of Latvia
latvia_map <- ne_countries(country = "Latvia", returnclass = "sf", scale = "medium")
```
# Cloroplet map
```{r}
pacman::p_load(geodata, sf, dplyr)
```
```{r}
# 1. Download Latvia's level 2 borders (Municipalities / Novadi)
# This saves a temporary file so it doesn't clutter your computer
latvia_raw <- gadm(country = "LVA", level = 2, path = tempdir())
# 2. Convert to an sf object and prep it for your spatial join
latvia_muni <- st_as_sf(latvia_raw) %>%
# Keep the municipality name column and the geometry
select(NAME_2, geometry) %>%
# Rename NAME_2 to LAU_ID so your existing choropleth code works perfectly!
rename(LAU_ID = NAME_2) %>%
st_transform(4326)
```
```{r}
# Perform a Spatial Join: this checks which polygon each point is inside
points_in_muni <- st_join(spatial_df, latvia_muni)
```
```{r}
# Calculate the average F-concentration for each municipality
muni_avg <- points_in_muni %>%
st_drop_geometry() %>% # Drop geometry temporarily to speed up the math
group_by(LAU_ID) %>% # Group by the municipality ID
summarise(Avg_F = mean(`F-concentration ppm`, na.rm = TRUE)) %>%
filter(!is.na(Avg_F)) # Remove empty groupings
# Merge those calculated averages back onto the main map polygons
choropleth_data <- latvia_muni %>%
left_join(muni_avg, by = "LAU_ID")
# 3. Build the Static Choropleth Map
static_choropleth <- ggplot(data = choropleth_data) +
# A. Plot the Polygons
# The 'fill' aesthetic colors the region by its average F-concentration
geom_sf(aes(fill = Avg_F), color = "white", linewidth = 0.3) +
# B. Overlay the original sampling points (Optional, but highly recommended)
# This shows the viewer exactly where the data came from within the colored region
geom_sf(data = spatial_df, size = 1.2, shape = 21, fill = "black", color = "white") +
# C. Apply the Viridis Palette
scale_fill_viridis_c(
option = "viridis",
name = "Avg F-conc.\n(ppm)",
na.value = "grey90" # Colors municipalities with NO data a neutral light grey
) +
# D. Add Cartographic Elements
annotation_scale(location = "bl", width_hint = 0.2) +
annotation_north_arrow(
location = "tl", which_north = "true",
style = north_arrow_fancy_orienteering()
) +
# E. Professional Formatting
theme_minimal() +
theme(
panel.grid.major = element_blank(), # Remove background grid
axis.text = element_blank(), # Remove Lat/Lon numbers
axis.title = element_blank(),
plot.title = element_text(face = "bold", size = 16),
legend.position = "right"
) +
labs(
title = "Average Fluoride Concentration by Municipality in Latvia",
subtitle = "Latvia Regional Division",
caption = "Data points represent specific sampling locations."
)
```
```{r}
static_choropleth
```
```{r}
# 4. Export the Figure to PDF
ggsave(
filename = "Fluoride_Choropleth_Latvia.pdf",
plot = static_choropleth,
device = "pdf",
width = 10,
height = 8,
dpi = 300
)
```