The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Spatial Analysis with nomisdata

Introduction

The nomisdata package integrates with R’s spatial ecosystem, particularly the sf package, to enable geographic analysis and mapping of UK labour market data.

Getting Spatial Data

Fetch with Boundaries

library(nomisdata)
library(sf)
library(ggplot2)

# Download data with KML boundaries
unemployment_spatial <- fetch_spatial(
  "NM_1_1",
  time = "latest",
  geography = "TYPE480",  # Regions
  measures = 20201,       # Rate
  sex = 7,
  parse_sf = TRUE         # Parse to sf object
)

# Check the object
class(unemployment_spatial)
#> [1] "sf"         "data.frame"

st_crs(unemployment_spatial)
#> Coordinate Reference System:
#>   WGS 84 / Pseudo-Mercator

Basic Mapping

# Simple choropleth
ggplot(unemployment_spatial) +
  geom_sf(aes(fill = OBS_VALUE), colour = "white", size = 0.3) +
  scale_fill_viridis_c(option = "magma", name = "Rate (%)") +
  labs(
    title = "Unemployment Rate by Region",
    caption = "Source: Nomis / ONS"
  ) +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
    legend.position = "right"
  )

Advanced Spatial Analysis

Joining Non-Spatial and Spatial Data

# Get detailed data without boundaries
detailed_data <- fetch_nomis(
  "NM_1_1",
  time = "latest",
  geography = "TYPE464",  # Local authorities
  measures = c(20100, 20201, 20203),
  sex = 7
)

# Get boundaries separately (lighter download)
boundaries <- fetch_spatial(
  "NM_1_1",
  time = "latest",
  geography = "TYPE464",
  measures = 20100,  # Just need one measure for boundaries
  sex = 7
)

# Join
combined <- boundaries |>
  select(GEOGRAPHY_CODE, geometry) |>
  left_join(
    detailed_data |> select(GEOGRAPHY_CODE, MEASURES_NAME, OBS_VALUE),
    by = "GEOGRAPHY_CODE"
  )

Spatial Aggregation

# Aggregate local authorities to regional level
la_data <- fetch_spatial(
  "NM_1_1",
  time = "latest",
  geography = "TYPE464",
  measures = 20100,
  sex = 7
)

# Get regional boundaries
regional_bounds <- fetch_spatial(
  "NM_1_1",
  time = "latest",
  geography = "TYPE480",
  measures = 20100,
  sex = 7
)

# Spatial join and aggregate
regional_aggregated <- st_join(
  la_data,
  regional_bounds |> select(region_name = GEOGRAPHY_NAME),
  join = st_within
) |>
  st_drop_geometry() |>
  group_by(region_name) |>
  summarise(total_claimants = sum(OBS_VALUE, na.rm = TRUE)) |>
  left_join(regional_bounds, by = c("region_name" = "GEOGRAPHY_NAME"))

Distance Analysis

# Calculate distance to nearest urban center
urban_centers <- data.frame(
  name = c("London", "Manchester", "Birmingham"),
  lon = c(-0.1276, -2.2426, -1.8904),
  lat = c(51.5074, 53.4808, 52.4862)
) |>
  st_as_sf(coords = c("lon", "lat"), crs = 4326)

# Calculate distances
la_centroids <- st_centroid(la_data)
distances <- st_distance(la_centroids, urban_centers)

# Add minimum distance to data
la_data$dist_to_urban <- apply(distances, 1, min)

Interactive Maps

library(leaflet)

# Create interactive map
unemployment_spatial |>
  st_transform(4326) |>  # Transform to WGS84 for leaflet
  leaflet() |>
  addTiles() |>
  addPolygons(
    fillColor = ~colorNumeric("YlOrRd", OBS_VALUE)(OBS_VALUE),
    fillOpacity = 0.7,
    color = "white",
    weight = 1,
    label = ~paste0(GEOGRAPHY_NAME, ": ", round(OBS_VALUE, 2), "%"),
    highlightOptions = highlightOptions(
      weight = 3,
      color = "#666",
      fillOpacity = 0.9,
      bringToFront = TRUE
    )
  ) |>
  addLegend(
    pal = colorNumeric("YlOrRd", unemployment_spatial$OBS_VALUE),
    values = ~OBS_VALUE,
    title = "Unemployment Rate (%)",
    position = "bottomright"
  )

Limitations

Resources

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.