Police patrol car representing public safety and crime data. Source: Unsplash (unsplash.com)

Introduction

This project explores nearly a decade of crime incident data reported in Montgomery County, Maryland, from July 2016 through May 2026. The dataset was collected and published by the Montgomery County Police Department (MCPD) through the county’s open data portal, dataMontgomery (data.montgomerycountymd.gov).

The dataset contains 490,372 incidents and 30 variables. The key variables I will use include:

My central research question is: What factors — including time of day, place type, crime category, and police district, predict the number of victims in a crime incident in Montgomery County, and how have crime patterns shifted across the county over time?

According to the dataMontgomery open data portal, the data is derived from reported crimes classified according to the National Incident-Based Reporting System (NIBRS) of the Criminal Justice Information Services (CJIS) Division Uniform Crime Reporting (UCR) Program, and documented by approved police incident reports. The data is compiled by “EJustice”, a law enforcement records management system used by the Montgomery County Police Department. The dataset includes all founded crimes reported after July 1st, 2016, and is refreshed on quarterly basis to reflect any changes in status due to ongoing police investigation. To protect victims’ privacy, no names or personal information are released. It is important to note that the data may reflect preliminary crime classifications that could change based on further investigation, and may include mechanical or human error (Montgomery County Police Department, 2026).

I chose this topic because I live in Montgomery County. Understanding local crime patterns, such as where crimes happen, when they peak, and what types are most common has real relevance to my daily life and community.

Background Research

Crime patterns in urban and suburban environments have been extensively studied through the lens of Routine Activity Theory, first proposed by Cohen and Felson (1979). The theory holds that crime occurs when three elements converge: a motivated offender, a suitable target, and the absence of a capable guardian. This framework predicts that crimes will peak during hours when residents leave their homes and concentrate in commercial or transit areas where targets are more accessible.

Research consistently shows that property crimes such as theft and vehicle break-ins tend to peak during daytime hours, while violent crimes and assaults are more common late at night (Haberman & Ratcliffe, 2015). Montgomery County’s suburban character, a mix of dense urban corridors like Silver Spring and Wheaton alongside quiet residential neighborhoods, makes it a particularly interesting case for testing these patterns.

Load the Libraries

library(tidyverse)
## Warning: package 'ggplot2' was built under R version 4.5.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   4.0.2     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── 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(plotly)
## Warning: package 'plotly' was built under R version 4.5.2
## 
## Attaching package: 'plotly'
## 
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following object is masked from 'package:graphics':
## 
##     layout
library(lubridate)
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.5.2

Load the dataset

setwd("~/Documents/Data 110")
crime <- read.csv("Crime_20260504.csv")
head(crime$Start_Date_Time)
## [1] "05/01/2026 04:05:00 AM" "05/01/2026 12:45:00 AM" "05/01/2026 12:45:00 AM"
## [4] "04/30/2026 11:08:00 PM" "04/30/2026 10:17:00 PM" "04/30/2026 10:15:00 PM"

Cleaning, EDA, and Wrangling

Exploring the Data

Before cleaning, I first checked for missing values using colSums(is.na()) and explored the structure of the dataset using str(). The dataset contains 490,372 observations and 30 variables.

colSums(is.na(crime))
##            Incident.ID           Offence.Code              CR.Number 
##                      0                      0                      0 
##   Dispatch.Date...Time        Start_Date_Time          End_Date_Time 
##                      0                      0                      0 
##             NIBRS.Code                Victims            Crime.Name1 
##                      0                      0                      0 
##            Crime.Name2            Crime.Name3   Police.District.Name 
##                      0                      0                      0 
##          Block.Address                   City                  State 
##                      0                      0                      0 
##               Zip.Code                 Agency                  Place 
##                   3439                      0                      0 
##                 Sector                   Beat                    PRA 
##                      0                      0                      0 
##         Address.Number          Street.Prefix            Street.Name 
##                  38557                      0                      0 
##          Street.Suffix            Street.Type               Latitude 
##                      0                      0                      0 
##              Longitude Police.District.Number               Location 
##                      0                      0                      0
str(crime)
## 'data.frame':    490372 obs. of  30 variables:
##  $ Incident.ID           : int  201573262 201573259 201573259 201573250 201573253 201573247 201573249 201573230 201573221 201573219 ...
##  $ Offence.Code          : chr  "9199" "5707" "9061" "9105" ...
##  $ CR.Number             : int  260018703 260018694 260018694 260018683 260018680 260018681 260018678 260018674 260018660 260018659 ...
##  $ Dispatch.Date...Time  : chr  "05/01/2026 04:05:27 AM" "05/01/2026 01:01:48 AM" "05/01/2026 01:01:48 AM" "04/30/2026 11:08:20 PM" ...
##  $ Start_Date_Time       : chr  "05/01/2026 04:05:00 AM" "05/01/2026 12:45:00 AM" "05/01/2026 12:45:00 AM" "04/30/2026 11:08:00 PM" ...
##  $ End_Date_Time         : chr  "" "" "" "" ...
##  $ NIBRS.Code            : chr  "90Z" "90J" "90Z" "90Z" ...
##  $ Victims               : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Crime.Name1           : chr  "Crime Against Society" "Crime Against Society" "Crime Against Society" "Crime Against Society" ...
##  $ Crime.Name2           : chr  "All Other Offenses" "Trespass of Real Property" "All Other Offenses" "All Other Offenses" ...
##  $ Crime.Name3           : chr  "POLICE INFORMATION" "TRESPASSING" "FUGITIVE FROM MD JURISDICTION" "LOST PROPERTY" ...
##  $ Police.District.Name  : chr  "SILVER SPRING" "ROCKVILLE" "ROCKVILLE" "ROCKVILLE" ...
##  $ Block.Address         : chr  "3900 BLK  MADISON PARK LA" "1600 BLK  ROCKVILLE PIK" "1600 BLK  ROCKVILLE PIK" "1  BLK W MONTGOMERY AVE" ...
##  $ City                  : chr  "BURTONSVILLE" "ROCKVILLE" "ROCKVILLE" "ROCKVILLE" ...
##  $ State                 : chr  "MD" "MD" "MD" "MD" ...
##  $ Zip.Code              : int  20866 20852 20852 20850 20874 20912 20852 20904 20814 20906 ...
##  $ Agency                : chr  "MCPD" "RCPD" "RCPD" "RCPD" ...
##  $ Place                 : chr  "Street - In vehicle" "Parking Lot - Commercial" "Parking Lot - Commercial" "Residence - Apartment/Condo" ...
##  $ Sector                : chr  "I" "A" "A" "A" ...
##  $ Beat                  : chr  "3I2" "1A2" "1A2" "1A1" ...
##  $ PRA                   : chr  "380" "266" "266" "255" ...
##  $ Address.Number        : int  3900 1600 1600 1 NA 8700 5700 12700 4800 13600 ...
##  $ Street.Prefix         : chr  "" "" "" "W" ...
##  $ Street.Name           : chr  "MADISON PARK" "ROCKVILLE" "ROCKVILLE" "MONTGOMERY" ...
##  $ Street.Suffix         : chr  "" "" "" "" ...
##  $ Street.Type           : chr  "LA" "PIK" "PIK" "AVE" ...
##  $ Latitude              : num  39.1 39.1 39.1 39.1 39.2 ...
##  $ Longitude             : num  -76.9 -77.1 -77.1 -77.2 -77.3 ...
##  $ Police.District.Number: chr  "3D" "1D" "1D" "1D" ...
##  $ Location              : chr  "    (39.0806, -76.9311)" "    (39.0629, -77.1248)" "    (39.0629, -77.1248)" "    (39.1457, -77.2037)" ...
names(crime) <- tolower(names(crime))
names(crime) <- gsub(" ","_",names(crime))
names(crime) <- gsub("\\.","_",names(crime))
head(crime)
##   incident_id offence_code cr_number   dispatch_date___time
## 1   201573262         9199 260018703 05/01/2026 04:05:27 AM
## 2   201573259         5707 260018694 05/01/2026 01:01:48 AM
## 3   201573259         9061 260018694 05/01/2026 01:01:48 AM
## 4   201573250         9105 260018683 04/30/2026 11:08:20 PM
## 5   201573253         5404 260018680 04/30/2026 10:17:49 PM
## 6   201573247         9113 260018681 04/30/2026 10:15:28 PM
##          start_date_time end_date_time nibrs_code victims           crime_name1
## 1 05/01/2026 04:05:00 AM                      90Z       1 Crime Against Society
## 2 05/01/2026 12:45:00 AM                      90J       1 Crime Against Society
## 3 05/01/2026 12:45:00 AM                      90Z       1 Crime Against Society
## 4 04/30/2026 11:08:00 PM                      90Z       1 Crime Against Society
## 5 04/30/2026 10:17:00 PM                      90D       1 Crime Against Society
## 6 04/30/2026 10:15:00 PM                      90Z       1 Crime Against Society
##                   crime_name2                         crime_name3
## 1          All Other Offenses                  POLICE INFORMATION
## 2   Trespass of Real Property                         TRESPASSING
## 3          All Other Offenses       FUGITIVE FROM MD JURISDICTION
## 4          All Other Offenses                       LOST PROPERTY
## 5 Driving Under the Influence  DRIVING UNDER THE INFLUENCE LIQUOR
## 6          All Other Offenses MENTAL ILLNESS - EMERGENCY PETITION
##   police_district_name             block_address         city state zip_code
## 1        SILVER SPRING 3900 BLK  MADISON PARK LA BURTONSVILLE    MD    20866
## 2            ROCKVILLE   1600 BLK  ROCKVILLE PIK    ROCKVILLE    MD    20852
## 3            ROCKVILLE   1600 BLK  ROCKVILLE PIK    ROCKVILLE    MD    20852
## 4            ROCKVILLE   1  BLK W MONTGOMERY AVE    ROCKVILLE    MD    20850
## 5           GERMANTOWN                             GERMANTOWN    MD    20874
## 6        SILVER SPRING      8700 BLK  GILBERT PL  TAKOMA PARK    MD    20912
##   agency                       place sector beat pra address_number
## 1   MCPD         Street - In vehicle      I  3I2 380           3900
## 2   RCPD    Parking Lot - Commercial      A  1A2 266           1600
## 3   RCPD    Parking Lot - Commercial      A  1A2 266           1600
## 4   RCPD Residence - Apartment/Condo      A  1A1 255              1
## 5   MCPD         Street - In vehicle      N  5N1 702             NA
## 6   MCPD Residence - Apartment/Condo      G  3G3 130           8700
##   street_prefix  street_name street_suffix street_type latitude longitude
## 1               MADISON PARK                        LA 39.08055  -76.9311
## 2                  ROCKVILLE                       PIK 39.06289  -77.1248
## 3                  ROCKVILLE                       PIK 39.06289  -77.1248
## 4             W   MONTGOMERY                       AVE 39.14570  -77.2037
## 5                    CENTURY                       BLV 39.19196  -77.2653
## 6                    GILBERT                        PL 38.99842  -76.9972
##   police_district_number                location
## 1                     3D     (39.0806, -76.9311)
## 2                     1D     (39.0629, -77.1248)
## 3                     1D     (39.0629, -77.1248)
## 4                     1D     (39.1457, -77.2037)
## 5                     5D      (39.192, -77.2653)
## 6                     3D     (38.9984, -76.9972)

I standardized all column names to lowercase with underscores using tolower() and gsub() to make them easier to work with in R.

crime$start_date_time <- mdy_hms(crime$start_date_time)
crime$year <- year(crime$start_date_time)
crime$hour <- hour(crime$start_date_time)

I parsed the start_date_time column using mdy_hms() from the lubridate to convert the datetime string into a POSIXct object that R can work with mathematically. I then extracted hour and year as new variables using hour() and year().

crime <- crime |>
  filter(
    crime_name1 != "Crime Against Not a Crime",
    police_district_name != "OTHER",
    )

I filtered out “Crime Against Not a Crime” entries which are administrative records rather than real crimes, and removed the 15 rows labeled “OTHER” for police district which are not meaningful for analysis.

crime_clean <- crime |>
  select(start_date_time, hour, year, victims, crime_name1, crime_name2, police_district_name, place, latitude, longitude)

I selected only the 10 variables relevant to my analysis, creating a clean dataset called crime_clean with 484,437 observations.

district_summary <- crime_clean |>
  group_by(police_district_name) |>
  summarize(
    total_incidents = n(),
    avg_victims = round(mean(victims), 3),
    max_victims = max(victims)
  ) |>
  arrange(desc(total_incidents))

district_summary
## # A tibble: 8 × 4
##   police_district_name total_incidents avg_victims max_victims
##   <chr>                          <int>       <dbl>       <int>
## 1 "SILVER SPRING"               101745        1.02          22
## 2 "WHEATON"                      89462        1.02           9
## 3 "MONTGOMERY VILLAGE"           81030        1.03           8
## 4 "BETHESDA"                     69349        1.01           8
## 5 "ROCKVILLE"                    66149        1.02           7
## 6 "GERMANTOWN"                   60895        1.03           7
## 7 "TAKOMA PARK"                  14334        1.01           4
## 8 ""                              1473        1.02           3

The district summary table shows that Silver Spring and Wheaton have the highest total incident counts, while Takoma Park has the fewest. The average number of victims across all districts is very close to 1, confirming that the vast majority of incidents involve a single victim.

crime_clean |>
  count(crime_name1, sort = TRUE )
##              crime_name1      n
## 1 Crime Against Property 237754
## 2  Crime Against Society 195316
## 3   Crime Against Person  51367

Crime Against Property is by far the most common category with 237,754 incidents, followed by Crime Against Society with 195,316, and Crime Against Person with 51,367.

Multiple Linear Regression

model <- lm(victims ~ hour + crime_name1 + police_district_name + place, data = crime_clean)
summary(model)
## 
## Call:
## lm(formula = victims ~ hour + crime_name1 + police_district_name + 
##     place, data = crime_clean)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -0.3603 -0.0036 -0.0006  0.0027 20.7902 
## 
## Coefficients:
##                                                Estimate Std. Error  t value
## (Intercept)                                   1.192e+00  2.696e-02   44.212
## hour                                          6.047e-05  3.798e-05    1.592
## crime_name1Crime Against Property            -2.075e-01  9.089e-04 -228.312
## crime_name1Crime Against Society             -2.066e-01  8.888e-04 -232.456
## police_district_nameBETHESDA                  4.131e-03  4.589e-03    0.900
## police_district_nameGERMANTOWN                9.417e-03  4.596e-03    2.049
## police_district_nameMONTGOMERY VILLAGE        5.183e-03  4.582e-03    1.131
## police_district_nameROCKVILLE                 4.225e-03  4.592e-03    0.920
## police_district_nameSILVER SPRING             6.478e-03  4.573e-03    1.416
## police_district_nameTAKOMA PARK              -1.650e-03  4.772e-03   -0.346
## police_district_nameWHEATON                   6.789e-03  4.578e-03    1.483
## placeAir/Bus/Train/Metro Terminal             7.397e-03  2.703e-02    0.274
## placeAmusement Park                           3.693e-01  6.115e-02    6.039
## placeArena/Stadium/Fairgrounds/Coliseum       5.050e-02  3.623e-02    1.394
## placeAtm Separate From Bank                   9.013e-03  4.066e-02    0.222
## placeAuto Dealership                          1.033e-02  2.687e-02    0.384
## placeAuto Repair                              5.827e-03  2.721e-02    0.214
## placeBank - ATM                               6.415e-03  2.686e-02    0.239
## placeBank/S&L/Credit Union                    9.974e-03  2.688e-02    0.371
## placeBar/Night Club                           3.860e-02  2.687e-02    1.437
## placeCamp / Campground                        5.257e-03  6.385e-02    0.082
## placeCheck Cashing Est.                       2.775e-03  3.020e-02    0.092
## placeChurch/Synagogue/Temple                  6.722e-03  2.705e-02    0.248
## placeCommercial - Industrial park            -5.856e-04  2.742e-02   -0.021
## placeCommercial - Office Building             2.515e-03  2.668e-02    0.094
## placeCommunity Center                        -1.789e-02  2.940e-02   -0.608
## placeConstruction Site                        3.994e-03  2.713e-02    0.147
## placeConvenience Store                        3.455e-03  2.665e-02    0.130
## placeCyberspace                               9.049e-03  2.685e-02    0.337
## placeDaycare Facility                        -3.266e-02  3.141e-02   -1.040
## placeDock/Wharf/Freight/Modal Terminal        9.710e-03  8.230e-02    0.118
## placeDoctor/Dentist/Vet Office               -1.066e-03  2.709e-02   -0.039
## placeFarm Facility                            4.641e-02  3.802e-02    1.221
## placeField/ Open Space                       -8.600e-03  2.782e-02   -0.309
## placeGambling Facility / Casino / Race Track  6.640e-03  1.260e-01    0.053
## placeGas Station                              3.031e-03  2.673e-02    0.113
## placeGolf Course                              1.694e-02  3.000e-02    0.565
## placeGovernment Building                      9.970e-03  2.668e-02    0.374
## placeGrocery/Supermarket                      5.513e-03  2.662e-02    0.207
## placeHospital/Emergency Care Center           2.312e-02  2.674e-02    0.865
## placeHotel/Motel/Etc.                         7.744e-04  2.671e-02    0.029
## placeIndustrial Site                         -1.696e-02  4.438e-02   -0.382
## placeJail/Prison                             -6.921e-03  2.745e-02   -0.252
## placeLake/Waterway                           -1.423e-02  3.332e-02   -0.427
## placeLaundromat                               5.216e-03  2.805e-02    0.186
## placeLibrary                                 -2.170e-03  2.728e-02   -0.080
## placeLiquor Store - Beer & Wine               8.127e-03  2.705e-02    0.300
## placeLiquor Store - County                    6.858e-03  2.719e-02    0.252
## placeMilitary Installation                   -1.325e-02  6.385e-02   -0.208
## placeNursery                                  1.500e-02  3.518e-02    0.426
## placeOther/Unknown                            6.553e-03  2.658e-02    0.247
## placePark                                     9.537e-03  2.679e-02    0.356
## placeParking Garage - Commercial              1.006e-02  2.679e-02    0.376
## placeParking Garage - County                  6.029e-03  2.682e-02    0.225
## placeParking Garage - Metro                  -9.118e-03  2.808e-02   -0.325
## placeParking Garage - Other                   9.662e-03  2.741e-02    0.353
## placeParking Garage - Residential             1.060e-02  2.669e-02    0.397
## placeParking Lot - Church                    -1.420e-03  2.778e-02   -0.051
## placeParking Lot - Commercial                 1.007e-02  2.660e-02    0.379
## placeParking Lot - County                     8.123e-03  2.703e-02    0.301
## placeParking Lot - Metro                      2.581e-02  2.798e-02    0.922
## placeParking Lot - Other                      8.126e-03  2.675e-02    0.304
## placeParking Lot - Park & Ride                7.473e-03  2.839e-02    0.263
## placeParking Lot - Rec Center                 1.640e-02  2.786e-02    0.589
## placeParking Lot - Residential                1.200e-02  2.658e-02    0.451
## placeParking Lot - School                     1.051e-02  2.704e-02    0.389
## placePawn Shop                                8.694e-03  3.348e-02    0.260
## placePedestrian Tunnel                       -9.882e-03  4.566e-02   -0.216
## placePool                                     2.224e-02  2.795e-02    0.796
## placeRecreation Center                        1.166e-03  2.696e-02    0.043
## placeRental Storage Facility                  9.315e-03  2.751e-02    0.339
## placeResidence - Apartment/Condo              1.023e-02  2.658e-02    0.385
## placeResidence - Apt Ofc/Storage              1.123e-03  2.693e-02    0.042
## placeResidence - Carport                      7.696e-03  2.884e-02    0.267
## placeResidence - Driveway                     9.960e-03  2.660e-02    0.374
## placeResidence - Garage                       9.231e-03  2.700e-02    0.342
## placeResidence - Mobile Home                  1.254e-03  2.976e-02    0.042
## placeResidence - Nursing Home                -9.972e-03  2.679e-02   -0.372
## placeResidence - Other                        3.907e-03  2.666e-02    0.147
## placeResidence - Shed                         8.911e-03  2.729e-02    0.327
## placeResidence - Single Family                6.470e-03  2.658e-02    0.243
## placeResidence - Yard                         1.804e-02  2.668e-02    0.676
## placeResidence -Townhouse/Duplex              1.774e-02  2.659e-02    0.667
## placeRest Area                                1.059e-02  8.230e-02    0.129
## placeRestaurant                               1.108e-02  2.663e-02    0.416
## placeRetail - Appliances/Electronics          8.246e-03  2.698e-02    0.306
## placeRetail - Beauty/Barber Shop              7.092e-03  2.745e-02    0.258
## placeRetail - Clothing                        8.744e-03  2.673e-02    0.327
## placeRetail - Department/Discount Store       8.668e-03  2.660e-02    0.326
## placeRetail - Drug Store/Pharmacy             6.993e-03  2.667e-02    0.262
## placeRetail - Dry Cleaner                     1.230e-02  3.011e-02    0.408
## placeRetail - Hardware                        6.806e-03  2.697e-02    0.252
## placeRetail - Jewelry                         1.016e-02  2.864e-02    0.355
## placeRetail - Mall                            1.087e-02  2.663e-02    0.408
## placeRetail - Other                           8.349e-03  2.665e-02    0.313
## placeRetail - Salon/Spa                      -2.869e-03  2.745e-02   -0.105
## placeRetail - Sporting Goods                  5.402e-03  2.731e-02    0.198
## placeRetail - Video Store                     3.720e-03  3.623e-02    0.103
## placeSchool - College/University             -2.147e-02  3.000e-02   -0.716
## placeSchool - Elementary/Secondary           -3.006e-03  2.664e-02   -0.113
## placeSchool/College - DO NOT USE             -2.695e-03  2.665e-02   -0.101
## placeShelter-Mission/Homeless                -7.700e-03  2.728e-02   -0.282
## placeStreet - Alley                           1.134e-02  2.715e-02    0.418
## placeStreet - Bus Stop                       -3.598e-03  2.673e-02   -0.135
## placeStreet - Commercial                      1.307e-02  2.662e-02    0.491
## placeStreet - In vehicle                      5.922e-03  2.658e-02    0.223
## placeStreet - Other                           1.039e-02  2.662e-02    0.390
## placeStreet - Residential                     1.133e-02  2.658e-02    0.426
## placeTheater                                  3.308e-02  2.859e-02    1.157
## placeWooded Area                             -6.428e-03  2.743e-02   -0.234
##                                              Pr(>|t|)    
## (Intercept)                                   < 2e-16 ***
## hour                                           0.1113    
## crime_name1Crime Against Property             < 2e-16 ***
## crime_name1Crime Against Society              < 2e-16 ***
## police_district_nameBETHESDA                   0.3680    
## police_district_nameGERMANTOWN                 0.0405 *  
## police_district_nameMONTGOMERY VILLAGE         0.2580    
## police_district_nameROCKVILLE                  0.3576    
## police_district_nameSILVER SPRING              0.1567    
## police_district_nameTAKOMA PARK                0.7294    
## police_district_nameWHEATON                    0.1381    
## placeAir/Bus/Train/Metro Terminal              0.7843    
## placeAmusement Park                          1.56e-09 ***
## placeArena/Stadium/Fairgrounds/Coliseum        0.1633    
## placeAtm Separate From Bank                    0.8246    
## placeAuto Dealership                           0.7008    
## placeAuto Repair                               0.8304    
## placeBank - ATM                                0.8112    
## placeBank/S&L/Credit Union                     0.7106    
## placeBar/Night Club                            0.1508    
## placeCamp / Campground                         0.9344    
## placeCheck Cashing Est.                        0.9268    
## placeChurch/Synagogue/Temple                   0.8038    
## placeCommercial - Industrial park              0.9830    
## placeCommercial - Office Building              0.9249    
## placeCommunity Center                          0.5429    
## placeConstruction Site                         0.8829    
## placeConvenience Store                         0.8968    
## placeCyberspace                                0.7361    
## placeDaycare Facility                          0.2984    
## placeDock/Wharf/Freight/Modal Terminal         0.9061    
## placeDoctor/Dentist/Vet Office                 0.9686    
## placeFarm Facility                             0.2222    
## placeField/ Open Space                         0.7572    
## placeGambling Facility / Casino / Race Track   0.9580    
## placeGas Station                               0.9097    
## placeGolf Course                               0.5723    
## placeGovernment Building                       0.7086    
## placeGrocery/Supermarket                       0.8359    
## placeHospital/Emergency Care Center            0.3871    
## placeHotel/Motel/Etc.                          0.9769    
## placeIndustrial Site                           0.7024    
## placeJail/Prison                               0.8009    
## placeLake/Waterway                             0.6693    
## placeLaundromat                                0.8525    
## placeLibrary                                   0.9366    
## placeLiquor Store - Beer & Wine                0.7639    
## placeLiquor Store - County                     0.8009    
## placeMilitary Installation                     0.8356    
## placeNursery                                   0.6699    
## placeOther/Unknown                             0.8052    
## placePark                                      0.7219    
## placeParking Garage - Commercial               0.7071    
## placeParking Garage - County                   0.8222    
## placeParking Garage - Metro                    0.7454    
## placeParking Garage - Other                    0.7245    
## placeParking Garage - Residential              0.6913    
## placeParking Lot - Church                      0.9592    
## placeParking Lot - Commercial                  0.7050    
## placeParking Lot - County                      0.7638    
## placeParking Lot - Metro                       0.3563    
## placeParking Lot - Other                       0.7613    
## placeParking Lot - Park & Ride                 0.7924    
## placeParking Lot - Rec Center                  0.5562    
## placeParking Lot - Residential                 0.6517    
## placeParking Lot - School                      0.6976    
## placePawn Shop                                 0.7951    
## placePedestrian Tunnel                         0.8286    
## placePool                                      0.4262    
## placeRecreation Center                         0.9655    
## placeRental Storage Facility                   0.7350    
## placeResidence - Apartment/Condo               0.7004    
## placeResidence - Apt Ofc/Storage               0.9667    
## placeResidence - Carport                       0.7896    
## placeResidence - Driveway                      0.7081    
## placeResidence - Garage                        0.7325    
## placeResidence - Mobile Home                   0.9664    
## placeResidence - Nursing Home                  0.7098    
## placeResidence - Other                         0.8835    
## placeResidence - Shed                          0.7440    
## placeResidence - Single Family                 0.8076    
## placeResidence - Yard                          0.4989    
## placeResidence -Townhouse/Duplex               0.5048    
## placeRest Area                                 0.8976    
## placeRestaurant                                0.6773    
## placeRetail - Appliances/Electronics           0.7599    
## placeRetail - Beauty/Barber Shop               0.7961    
## placeRetail - Clothing                         0.7435    
## placeRetail - Department/Discount Store        0.7446    
## placeRetail - Drug Store/Pharmacy              0.7932    
## placeRetail - Dry Cleaner                      0.6830    
## placeRetail - Hardware                         0.8008    
## placeRetail - Jewelry                          0.7229    
## placeRetail - Mall                             0.6832    
## placeRetail - Other                            0.7540    
## placeRetail - Salon/Spa                        0.9167    
## placeRetail - Sporting Goods                   0.8432    
## placeRetail - Video Store                      0.9182    
## placeSchool - College/University               0.4742    
## placeSchool - Elementary/Secondary             0.9101    
## placeSchool/College - DO NOT USE               0.9195    
## placeShelter-Mission/Homeless                  0.7777    
## placeStreet - Alley                            0.6761    
## placeStreet - Bus Stop                         0.8929    
## placeStreet - Commercial                       0.6233    
## placeStreet - In vehicle                       0.8237    
## placeStreet - Other                            0.6964    
## placeStreet - Residential                      0.6699    
## placeTheater                                   0.2474    
## placeWooded Area                               0.8147    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1742 on 484327 degrees of freedom
## Multiple R-squared:  0.1199, Adjusted R-squared:  0.1197 
## F-statistic: 605.5 on 109 and 484327 DF,  p-value: < 2.2e-16
par(mfrow=c(2,2)); plot(model); par(mfrow=c(1,1))

Regression Analysis

Model equation:

Victims = β₀ + β₁(hour) + β₂(crime_name1) + β₃(police_district_name) + β₄(place) + ε

Adjusted R²: 0.1197

The adjusted R² of 0.12 means our predictors explain about 12% of the variation in victim counts. While this may seem low, it is expected as the vast majority of incidents involve exactly one victim, so there is very little variation to explain.

Key findings from the model:

  • Hour is not a significant predictor (p = 0.111), suggesting the time of day does not meaningfully change the number of victims per incident.

  • Crime category is highly significant, both “Crime Against Property” and “Crime Against Society” are associated with significantly fewer victims compared to “Crime Against Person” (both p < 2e-16). This makes sense as violent crimes are more likely to involve multiple victims.

  • Police district is largely not significant, except Germantown (p = 0.04), suggesting location within the county has minimal effect on victim count.

  • Amusement Park as a place type is the strongest significant predictor (p = 1.56e-09), associated with higher victim counts, likely reflecting incidents at crowded public venues.

    Diagnostic Plots

  • Residuals vs Fitted: The residuals are not evenly spread around zero, which suggests the model does not perfectly meet the linearity. This is expected given that victims is a count variable that is heavily skewed toward 1.

  • Q-Q Residuals: The points deviate significantly from the diagonal line at the upper tail, confirming the residuals are not normally distributed. Again this is expected, with 98% of incidents having exactly one victim, the outcome variable is not normally distributed to begin with.

  • Scale-Location: The upward trend in this plot suggests heteroscedasticity, meaning the variance of residuals is not constant across fitted values.

  • Residuals vs Leverage: A few high leverage points appear to have outsized influence on the model. These likely represent rare incidents with unusually high victim counts such as mass casualty events.

Overall these diagnostic plots confirm that while linear regression reveals statistically significant predictors, the model has limitations due to the non-normal nature of the outcome variable.

Visualization 1: Crime Frequency by Hour of Day

hourly_crime <- crime_clean |>
  group_by(hour, crime_name1) |>
  summarize(count = n(), .groups = "drop")
p1 <- ggplot(hourly_crime, aes(x = hour, y = count, color = crime_name1)) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 2, alpha = 0.7) +
  scale_color_manual(
    values = c(
      "Crime Against Property" = "#E07B39",
      "Crime Against Person"   = "#2E4057",
      "Crime Against Society"  = "#048A81"
    )
  ) +
  scale_x_continuous(breaks = seq(0, 23, by = 2)) +
  labs(
    title    = "Crime Frequency by Hour of Day in Montgomery County, MD (2016–2026)",
    subtitle = "Property crimes peak mid-morning; crimes against persons spike late at night",
    x        = "Hour of Day (24-hour clock)",
    y        = "Number of Incidents",
    color    = "Crime Category",
    caption  = "Source: Montgomery County Police Department via dataMontgomery"
  ) +
  theme_minimal()

ggplotly(p1, tooltip = c("x", "y", "color"))

This interactive line chart displays the frequency of crime incidents by hour of day across three major crime categories in Montgomery County, Maryland from 2016 to 2026. Crime Against Property (shown in orange) follows a clear pattern, dropping to its lowest point around 4–5 AM and then rising sharply through the morning, peaking around noon before gradually declining through the evening. Crime Against Society (teal) follows a similar shape but with a notable spike at midnight, likely reflecting drug and alcohol related offenses during late night hours. Crime Against Person (dark blue) remains relatively low and stable throughout the day compared to the other categories. A surprising finding is the spike across all three categories at midnight (hour 0), which may reflect how incidents that occur late at night get logged at exactly 12:00 AM when the exact time is unknown. Overall this visualization supports the Routine Activity Theory: property crimes peak when people are out and about during the day, while society-related offenses concentrate during nighttime hours.

Visualization 2: Annual Crime Incidents by Police District Over Time

yearly_district <- crime_clean |>
  filter(year >= 2017 & year <= 2025) |>
  group_by(year, police_district_name) |>
  summarize(total = n(), .groups = "drop")
ggplot(yearly_district, aes(x = year, y = total, fill = police_district_name)) +
  geom_col(position = "dodge") +
  scale_fill_manual(
    values = c(
      "SILVER SPRING"      = "#2E4057",
      "WHEATON"            = "#E07B39",
      "MONTGOMERY VILLAGE" = "#048A81",
      "BETHESDA"           = "#D4A017",
      "ROCKVILLE"          = "#7B2D8B",
      "GERMANTOWN"         = "#C0392B",
      "TAKOMA PARK"        = "#1A7A4A"
    )
  ) +
  scale_x_continuous(breaks = 2017:2025) +
  labs(
    title    = "Annual Crime Incidents by Police District in Montgomery County, MD (2017–2025)",
    subtitle = "Silver Spring and Wheaton consistently lead in incident counts",
    x        = "Year",
    y        = "Number of Incidents",
    fill     = "Police District",
    caption  = "Source: Montgomery County Police Department via dataMontgomery"
  ) +
  theme_economist() 

This grouped bar chart displays the total number of crime incidents per police district in Montgomery County from 2017 to 2025. Silver Spring and Wheaton consistently record the highest incident counts each year, which reflects their denser urban character and higher population compared to other districts. A noticeable dip is visible across nearly all districts in 2020 and 2021, caused by the COVID-19 pandemic. Reduced movement, business closures, and stay at home orders likely suppressed crime activity during this period. Incident counts began recovering after the pandemic by 2022 and 2023. Takoma Park consistently shows the lowest counts throughout the entire period, reflecting its smaller geographic size and population relative to other districts. Montgomery Village also shows unusually low counts in 2020 and 2021 before recovering, suggesting it was particularly affected by pandemic related disruptions.

Visualization 3: Geographic Map of Crime Incidents (Tableau)

Crime Incidents by Location and Category in Montgomery County, MD (2016–2026)

This Tableau map plots over 61,000 crime incidents across Montgomery County, Maryland, color coded by crime category. Crime Against Property (orange) dominates the map and is densely concentrated in the southern portion of the county particularly around Silver Spring and Wheaton which are the most commercially dense and populated areas. Crime Against Person (pink/red) and Crime Against Society (teal) appear more scattered but also cluster in the same southern areas The northern areas of the county show noticeably fewer incidents overall, reflecting the more suburban and rural character of those neighborhoods. The closeness to Washington D.C. in the south is clearly visible and likely contributes to higher crime density in that region due to higher population and traffic flow.

Conclusion

This project explored nearly 490,000 crime incidents recorded in Montgomery County, Maryland between July 2016 and May 2026. Data cleaning involved standardizing column names using tolower() and gsub(), parsing the start_date_time column using mdy_hms() from lubridate, extracting hour and year with hour() and year(), filtering out crimes that weren’t crimes but they were just put there using filter(), selecting relevant variables with select(), and summarizing patterns using group_by(), summarize(), arrange(), and count().

The first visualization, an interactive line chart, displays crime frequency by hour of day across three major crime categories. The most surprising pattern was the spike across all three categories at hour 0 (midnight), which likely reflects incidents that occur late at night being logged at exactly 12:00 AM when the precise time is unknown rather than a true surge in crime at midnight. The second visualization, a grouped bar chart, shows annual crime counts by police district from 2017 to 2025. The most interesting and unexpected pattern was the visible COVID-19 dip in 2020 and 2021 across every district.Something I did not anticipate finding when I first explored the dataset. The third visualization, a Tableau geographic map, plots over 61,000 crime incidents across Montgomery County color coded by crime category, revealing that crime is heavily concentrated in the southern portion of the county near Silver Spring, Wheaton, and the DC border.

One element I wished I could have included is a year over year breakdown by specific offense type. For example tracking how shoplifting, motor vehicle theft, and simple assault each changed before, during, and after COVID-19. I attempted to create this visualization but the large number of offense types in crime_name2 made the chart too cluttered to be readable. I also wished I could have embedded the Tableau map directly as an interactive element inside the rendered HTML rather than linking out to Tableau Public, but was unable to get the embed code to render correctly in Quarto.

References

Background Information Sources

Cohen, L. E., & Felson, M. (1979). Social change and crime rate trends: A routine activity approach. American Sociological Review, 44(4), 588–608. https://www.jstor.org/stable/2094589

Grolemund, G., & Wickham, H. (2011). Dates and times made easy with lubridate. Journal of Statistical Software, 40(3), 1–25. https://www.jstatsoft.org/article/view/v040i03

Haberman, C. P., & Ratcliffe, J. H. (2015). Testing for temporally differentiated relationships among potentially criminogenic places and census block street robbery counts. Criminology, 53(3), 457–483. https://doi.org/10.1111/1745-9125.12076

Montgomery County Police Department. (2026). Crime data [Data set]. dataMontgomery. https://data.montgomerycountymd.gov/Public-Safety/Crime/icn6-v9z3

Coding Sources

I used this source for my first visualization. This source helped me understand and use plotly correctly.

Sievert, C. (2020). Converting ggplot2 to plotly. In Interactive web-based data visualization with R, plotly, and shiny. Chapman and Hall/CRC. https://plotly-r.com/overview.html