Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

RadvancedaiAI generated

Spatial Analysis of Crime Data with sf

Build an R analysis that maps where crimes happen across a city. You'll load real, publicly available crime incident data with coordinates, match each incident to the neighborhood it happened in using a spatial join, and calculate incident density per square kilometer and per 1,000 residents. The result is a set of choropleth maps (maps where each neighborhood is colored by its value), with the top hotspots labeled, plus a short report on what the data shows. You'll learn how to work with spatial data in R using the sf package: reading shapefiles and GeoJSON, coordinate reference systems, spatial joins, area calculations, and mapping with ggplot2's geom_sf. A good choice of data is the City of Chicago's open data portal, which publishes both crime incidents and neighborhood (community area) boundaries.

Estimate
~13h
Steps
7
Completed by
0
Proposed by
codeseed.app

sf · ggplot2 · dplyr

Project roadmap

  1. 01

    Get the data

    ~1.5h

    Download one year of crime incidents with latitude and longitude, and the matching neighborhood boundaries, from a city's open data portal (Chicago's works well), plus a population figure per neighborhood. Put the files in data/raw/ and write down the source URL and download date of each in data/README.md. Done when: the three files and data/README.md are in the repo.

  2. 02

    Load and clean the data with sf

    ~2h

    Read the boundaries with sf::st_read. Read the incidents with readr, drop rows with missing or clearly wrong coordinates (for example 0,0), and convert them to an sf object with st_as_sf, using crs = 4326 (latitude/longitude). Print how many rows were kept and dropped. Done when: both datasets load as sf objects and the cleaning numbers are printed.

  3. 03

    Match coordinate systems

    ~1.5h

    Latitude/longitude can't be used to measure areas in km², so transform both layers with st_transform to a projected coordinate system in meters suited to the city (for Chicago, EPSG:26971 or UTM zone 16N). Check with st_crs that both layers now use the same system. Done when: both layers share the same projected CRS.

  4. 04

    Count incidents per neighborhood

    ~2h

    Use st_join to attach each incident to the neighborhood polygon that contains it, then count incidents per neighborhood with dplyr, including neighborhoods with zero incidents. Report how many incidents fell outside every boundary. Done when: a table has one row per neighborhood with its incident count.

  5. 05

    Compute density measures

    ~1.5h

    Calculate each neighborhood's area in km² with st_area, then two measures: incidents per km² and incidents per 1,000 residents, joined from the population data. Explain in a comment why the two measures can rank neighborhoods differently. Done when: both measures are computed for every neighborhood.

  6. 06

    Build choropleth maps

    ~2.5h

    Plot each measure as a map with ggplot2's geom_sf, using a sequential color scale such as viridis, a clear title and a legend with units. Label the 10 highest-density neighborhoods with their names using geom_sf_text or geom_sf_label, and save the maps as PNG files in output/. Done when: both maps are saved in output/ with the top 10 neighborhoods labeled.

  7. 07

    Write a short report

    ~2h

    Create a Quarto or R Markdown report that runs the whole analysis from the raw files and includes both maps, a table of the top 10 neighborhoods for each measure, and a few paragraphs on what the maps show and their limits, such as reporting differences and population estimates. Done when: rendering the report from a clean session produces an HTML file with the maps, tables and text.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~13h · 7 steps

Tech stack

sfggplot2dplyr