R Markdown

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.0     ✔ readr     2.1.6
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.3     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.1     
## ── 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(readxl)
library(pastecs)
## 
## Attaching package: 'pastecs'
## 
## The following objects are masked from 'package:dplyr':
## 
##     first, last
## 
## The following object is masked from 'package:tidyr':
## 
##     extract
safedash_offenses <- read_excel("safedash_offenses.xlsx")
## New names:
## • `` -> `...1`
names(safedash_offenses)
## [1] "...1"                "Report_Date"         "NIBRS_Code_Name"    
## [4] "NIBRS_Crime_Against" "Service_Area"        "NIBRS_Group"        
## [7] "Zip_Code"            "DateTime"
str(safedash_offenses)
## tibble [538,978 × 8] (S3: tbl_df/tbl/data.frame)
##  $ ...1               : num [1:538978] 5.37e+10 6.02e+10 6.43e+10 7.24e+10 5.01e+10 ...
##  $ Report_Date        : POSIXct[1:538978], format: "2024-01-12" "2024-10-22" ...
##  $ NIBRS_Code_Name    : chr [1:538978] "Impersonation" "Pornography/Obscene Material" "Pornography/Obscene Material" "Pornography/Obscene Material" ...
##  $ NIBRS_Crime_Against: chr [1:538978] "PROPERTY" "SOCIETY" "SOCIETY" "SOCIETY" ...
##  $ Service_Area       : chr [1:538978] "WEST" "WEST" "CENTRAL" "WEST" ...
##  $ NIBRS_Group        : chr [1:538978] "Fraud Offenses" "Pornography/Obscene Material" "Pornography/Obscene Material" "Pornography/Obscene Material" ...
##  $ Zip_Code           : chr [1:538978] "78201" "78201" "78201" "78201" ...
##  $ DateTime           : POSIXct[1:538978], format: "2026-09-01" "2026-09-01" ...

Exploring Correlations

safedash_offenses %>%
  count(NIBRS_Group, sort = TRUE)
## # A tibble: 24 × 2
##    NIBRS_Group                                   n
##    <chr>                                     <int>
##  1 Larceny/Theft Offenses                   180014
##  2 Assault Offenses                         105827
##  3 Destruction/Damage/Vandalism of Property  69599
##  4 Motor Vehicle Theft                       48239
##  5 Drug/Narcotics Offenses                   39323
##  6 Fraud Offenses                            34990
##  7 Breaking & Entering                       26463
##  8 Sex Offenses, Forcible                     8172
##  9 Weapon Law Violations                      6943
## 10 Robbery                                    5846
## # ℹ 14 more rows
daily_offenses <- safedash_offenses %>%
  count(Report_Date, name = "offense_count")

head(daily_offenses)
## # A tibble: 6 × 2
##   Report_Date         offense_count
##   <dttm>                      <int>
## 1 2023-01-01 00:00:00           378
## 2 2023-01-02 00:00:00           441
## 3 2023-01-03 00:00:00           484
## 4 2023-01-04 00:00:00           443
## 5 2023-01-05 00:00:00           426
## 6 2023-01-06 00:00:00           423
top_groups <- safedash_offenses %>%
  count(NIBRS_Group, sort = TRUE) %>%
  slice_head(n = 5)

top_groups
## # A tibble: 5 × 2
##   NIBRS_Group                                   n
##   <chr>                                     <int>
## 1 Larceny/Theft Offenses                   180014
## 2 Assault Offenses                         105827
## 3 Destruction/Damage/Vandalism of Property  69599
## 4 Motor Vehicle Theft                       48239
## 5 Drug/Narcotics Offenses                   39323
ggplot(top_groups, aes(x = reorder(NIBRS_Group, n), y = n)) +
  geom_col() +
  coord_flip() +
  labs(
    title = "Top Five Reported Offense Groups",
    x = "Offense Group",
    y = "Number of Reported Offenses"
  ) +
  theme_minimal()

The results show that larceny/theft offenses were the most frequently reported offense group in the dataset, followed by assault offenses. Destruction/damage/vandalism of property, motor vehicle theft, and drug/narcotics offenses were also among the five most frequently reported groups. This provides an overview of the most common reported offenses in the dataset and helps identify areas for further analysis.

Exploring Daily Offense Patterns

I grouped the reported offenses by date to examine how the number of reported offenses changes over time.

ggplot(daily_offenses, aes(x = Report_Date, y = offense_count)) +
  geom_line() +
  labs(
    title = "Daily Reported Offenses Over Time",
    x = "Report Date",
    y = "Number of Reported Offenses"
  ) +
  theme_minimal()

daily_offenses <- daily_offenses %>%
  mutate(day_number = row_number())

cor(daily_offenses$day_number,
    daily_offenses$offense_count,
    use = "complete.obs")
## [1] -0.5807591

The correlation analysis produced a value of approximately -0.58, indicating a moderate negative relationship between the order of days and the number of reported offenses. This suggests that daily offense counts tended to be lower later in the period than earlier in the period. However, this result does not explain why the counts changed over time.