Crime Density in Seattle

Posted on Nov 11, 2015

Contributed by Daniel Donohue.  Daniel was a student of the NYC Data Science Academy 12-week full-time data science bootcamp from Sep. 23 to Dec. 18, 2015.  This post was based on his second in-class project (due after the 4th week of the program).

Daniel Michael Donohue

11 November 2015


For my second project, which was to build and deploy an application made in Shiny, I chose to focus on a dataset of police report incidents in Seattle, WA.  What I did with this dataset is make an interactive heat map of crime density based on a user's selection of a date range and a subset of offense types.  Theoretically, it could be used to vet a neighborhood's safety (for instance, if a person is moving and wants to see what their new neighborhood is like), or to give law enforcement information so that they can more effectively battle certain types of crime.

The Application

You can demo the application here (please don't forget to close your browser's window when you're done!)

The application itself has four main components.  Along the left-hand side the user will find a place to enter a range of dates, and a checkbox group where they can select which types of crimes they want to be displayed.  The main panel contains a leaflet map, with a heat map overlaid.  The base map layer is created through the R package rChart's binding to the Leaflet library:

output$ <- renderMap({ <- Leaflet$new()$setView(c(47.5982623, -122.3415519), 12)$tileLayer(provider = "Esri.WorldStreetMap")

This creates the map layer, centers it on a particular latitude/longitude, sets an appropriate zoom level, and chooses the style of the map.  The heat layer component depends entirely on Leaflet.heat, a JavaScript plugin written by Vladimir Agafonkin.  It requires a JSON object of latitude/longitude pairs.  When a user selects a range of dates and a subset of crimes, the reactive element

get.spd.arr <- reactive({
spd.dat <- spd[spd$Offense %in% input$sel.crime &
(spd$Date >= input$[1] &
spd$Date <= input$[2]), ]
spd.arr <- toJSONArray2(spd.dat[c(3, 4)], json = FALSE, names = FALSE)

subsets the spd dataframe (the object containing all observations) based on the selection, and returns a JSON array of latitude/longitude pairs to be fed into the heat layer function:

output$ <- renderUI({
tags$body(tags$script(HTML(sprintf("var addressPoints = %s
if (typeof heat === typeof undefined) {
heat = L.heatLayer(addressPoints, {maxZoom: 9, radius: 20, blur: 30});
} else {
heat.setOptions({maxZoom: 9, radius: 20, blur: 30});
", rjson::toJSON(get.spd.arr())

This takes the JSON array returned by the reactive element, converts it to a JSON object, and then supplies this to the JavaScript function heatLayer, which draws the heat layer on top of the Leaflet map based on the closeness of latitude/longitude pairs.  Originally, the heat layer was being placed over existing heat layers every time the state of the map changed, so the if...else statement is a bit of JavaScript that prevents this from happening.


Working with Shiny was fun.  There's a lot you can do with it, and I look forward to incorporating it into future projects.  If I were to improve on this project, I would like to have a user be able to enter an address or a name of a landmark, and have the map automatically zoom in on that location.  It would also be useful to have the application be updated as new police reports are added to the dataset.  Finally, it would be nice to expand to other cities.

The code that makes the application can be found here.

About Author

Daniel Donohue

Daniel Donohue (A.B. Mathematics, M.S. Mathematics) spent the last three years as a Ph.D. student in mathematics studying topics in algebraic geometry, but decided a few short months ago that he needed a change in venue and career....
View all posts by Daniel Donohue >

Related Articles

Leave a Comment

No comments found.

View Posts by Categories

Our Recent Popular Posts

View Posts by Tags

#python #trainwithnycdsa 2019 airbnb Alex Baransky alumni Alumni Interview Alumni Reviews Alumni Spotlight alumni story Alumnus API Application artist aws beautiful soup Best Bootcamp Best Data Science 2019 Best Data Science Bootcamp Best Data Science Bootcamp 2020 Best Ranked Big Data Book Launch Book-Signing bootcamp Bootcamp Alumni Bootcamp Prep Bundles California Cancer Research capstone Career Career Day citibike clustering Coding Course Demo Course Report D3.js data Data Analyst data science Data Science Academy Data Science Bootcamp Data science jobs Data Science Reviews Data Scientist Data Scientist Jobs data visualization Deep Learning Demo Day Discount dplyr employer networking feature engineering Finance Financial Data Science Flask gbm Get Hired ggplot2 googleVis Hadoop higgs boson Hiring hiring partner events Hiring Partners Industry Experts Instructor Blog Instructor Interview Job Job Placement Jobs Jon Krohn JP Morgan Chase Kaggle Kickstarter lasso regression Lead Data Scienctist Lead Data Scientist leaflet linear regression Logistic Regression machine learning Maps matplotlib Medical Research Meet the team meetup Networking neural network Neural networks New Courses nlp NYC NYC Data Science nyc data science academy NYC Open Data NYCDSA NYCDSA Alumni Online Online Bootcamp Online Training Open Data painter pandas Part-time Portfolio Development prediction Prework Programming PwC python Python Data Analysis python machine learning python scrapy python web scraping python webscraping Python Workshop R R language R Programming R Shiny r studio R Visualization R Workshop R-bloggers random forest Ranking recommendation recommendation system regression Remote remote data science bootcamp Scrapy scrapy visualization seaborn Selenium sentiment analysis Shiny Shiny Dashboard Spark Special Special Summer Sports statistics streaming Student Interview Student Showcase SVM Switchup Tableau team TensorFlow Testimonial tf-idf Top Data Science Bootcamp twitter visualization web scraping Weekend Course What to expect word cloud word2vec XGBoost yelp