setwd('/Users/giulia/datasci_course_materials/Assignments/assignment6')
library(ggplot2)#data visualization
library(ggthemes) #data visualization
library(plyr) #data manipulation
library(dplyr) #data manipulation
library(lubridate) #date manipulation
library(RColorBrewer) #data visualization
library(maptools)#map manipulation
library(rgeos) #map manipulation
library(scales) #data visualization
library(ggmap)#map visualization

Key take away

Thieves are particularly active in San FranCisco and like the Eastern coast and the afternoon hours better. If you’re in the Southern district though, you should keep your eyes open all the day!

Load data

SanFran =read.csv('sanfrancisco_incidents_summer_2014.csv',na.strings=c(""))
#Seattle = read.csv('seattle_incidents_summer_2014.csv',na.strings=c(""))

San Francisco

Exploring the dataset

First, I give a look at the data

summary(SanFran)
##    IncidntNum                  Category   
##  Min.   : 10284385   LARCENY/THEFT :9466  
##  1st Qu.:140545607   OTHER OFFENSES:3567  
##  Median :140632022   NON-CRIMINAL  :3023  
##  Mean   :142017280   ASSAULT       :2882  
##  3rd Qu.:140719664   VEHICLE THEFT :1966  
##  Max.   :990367398   WARRANTS      :1782  
##                      (Other)       :6307  
##                          Descript         DayOfWeek            Date      
##  GRAND THEFT FROM LOCKED AUTO: 3766   Friday   :4451   06/28/2014:  410  
##  STOLEN AUTOMOBILE           : 1350   Monday   :4005   08/09/2014:  410  
##  LOST PROPERTY               : 1202   Saturday :4319   08/08/2014:  403  
##  PETTY THEFT OF PROPERTY     : 1125   Sunday   :4218   06/29/2014:  397  
##  WARRANT ARREST              :  980   Thursday :3968   08/29/2014:  388  
##  PETTY THEFT FROM LOCKED AUTO:  955   Tuesday  :3930   06/04/2014:  380  
##  (Other)                     :19615   Wednesday:4102   (Other)   :26605  
##       Time           PdDistrict             Resolution   
##  12:00  :  784   SOUTHERN :5739   NONE           :19139  
##  00:01  :  661   MISSION  :3700   ARREST, BOOKED : 6502  
##  18:00  :  649   NORTHERN :3589   ARREST, CITED  : 1419  
##  19:00  :  621   CENTRAL  :3513   LOCATED        : 1042  
##  17:00  :  594   BAYVIEW  :2725   UNFOUNDED      :  260  
##  20:00  :  586   INGLESIDE:2378   JUVENILE BOOKED:  163  
##  (Other):25098   (Other)  :7349   (Other)        :  468  
##                      Address            X                Y        
##  800 Block of BRYANT ST  :  948   Min.   :-122.5   Min.   :37.71  
##  800 Block of MARKET ST  :  288   1st Qu.:-122.4   1st Qu.:37.76  
##  900 Block of POTRERO AV :  230   Median :-122.4   Median :37.78  
##  1000 Block of POTRERO AV:  199   Mean   :-122.4   Mean   :37.77  
##  2000 Block of MISSION ST:  149   3rd Qu.:-122.4   3rd Qu.:37.79  
##  16TH ST / MISSION ST    :  116   Max.   :-122.4   Max.   :37.82  
##  (Other)                 :27063                                   
##                                   Location          PdId          
##  (37.775420706711, -122.403404791479) :  940   Min.   :1.028e+12  
##  (37.7571580431915, -122.406604919508):  224   1st Qu.:1.405e+13  
##  (37.7564864109309, -122.406539115148):  196   Median :1.406e+13  
##  (37.7650501214668, -122.419671780296):  152   Mean   :1.420e+13  
##  (37.7841893501425, -122.407633520742):  150   3rd Qu.:1.407e+13  
##  (37.7285280627465, -122.475647460786):  102   Max.   :9.904e+13  
##  (Other)                              :27229
str(SanFran)
## 'data.frame':    28993 obs. of  13 variables:
##  $ IncidntNum: int  140734311 140736317 146177923 146177531 140734220 140734349 140734349 140734349 140738147 140734258 ...
##  $ Category  : Factor w/ 34 levels "ARSON","ASSAULT",..: 1 20 16 16 20 7 7 6 21 30 ...
##  $ Descript  : Factor w/ 368 levels "ABANDONMENT OF CHILD",..: 15 179 143 143 132 247 239 93 107 347 ...
##  $ DayOfWeek : Factor w/ 7 levels "Friday","Monday",..: 4 4 4 4 4 4 4 4 4 4 ...
##  $ Date      : Factor w/ 92 levels "06/01/2014","06/02/2014",..: 92 92 92 92 92 92 92 92 92 92 ...
##  $ Time      : Factor w/ 1379 levels "00:01","00:02",..: 1370 1365 1351 1351 1344 1334 1334 1334 1321 1321 ...
##  $ PdDistrict: Factor w/ 10 levels "BAYVIEW","CENTRAL",..: 1 4 8 7 7 8 8 8 3 2 ...
##  $ Resolution: Factor w/ 16 levels "ARREST, BOOKED",..: 12 12 12 12 12 1 1 1 12 2 ...
##  $ Address   : Factor w/ 8055 levels "0 Block of 10TH ST",..: 6843 4022 1098 6111 5096 1263 1263 1263 1575 5236 ...
##  $ X         : num  -122 -122 -122 -122 -123 ...
##  $ Y         : num  37.7 37.8 37.8 37.8 37.8 ...
##  $ Location  : Factor w/ 8732 levels "(37.7080829769301, -122.419241455854)",..: 1970 3730 5834 4802 4777 4993 4993 4993 2543 7598 ...
##  $ PdId      : num  1.41e+13 1.41e+13 1.46e+13 1.46e+13 1.41e+13 ...
head(SanFran)
##   IncidntNum      Category                     Descript DayOfWeek
## 1  140734311         ARSON           ARSON OF A VEHICLE    Sunday
## 2  140736317  NON-CRIMINAL                LOST PROPERTY    Sunday
## 3  146177923 LARCENY/THEFT GRAND THEFT FROM LOCKED AUTO    Sunday
## 4  146177531 LARCENY/THEFT GRAND THEFT FROM LOCKED AUTO    Sunday
## 5  140734220  NON-CRIMINAL               FOUND PROPERTY    Sunday
## 6  140734349 DRUG/NARCOTIC      POSSESSION OF MARIJUANA    Sunday
##         Date  Time PdDistrict     Resolution                   Address
## 1 08/31/2014 23:50    BAYVIEW           NONE LOOMIS ST / INDUSTRIAL ST
## 2 08/31/2014 23:45    MISSION           NONE    400 Block of CASTRO ST
## 3 08/31/2014 23:30   SOUTHERN           NONE  1000 Block of MISSION ST
## 4 08/31/2014 23:30   RICHMOND           NONE       FULTON ST / 26TH AV
## 5 08/31/2014 23:23   RICHMOND           NONE  800 Block of LA PLAYA ST
## 6 08/31/2014 23:13   SOUTHERN ARREST, BOOKED        11TH ST / MINNA ST
##           X        Y                              Location         PdId
## 1 -122.4056 37.73832 (37.7383221869053, -122.405646994567) 1.407343e+13
## 2 -122.4350 37.76177 (37.7617677182954, -122.435012093789) 1.407363e+13
## 3 -122.4098 37.78004 (37.7800356268394, -122.409795194505) 1.461779e+13
## 4 -122.4853 37.77252 (37.7725176473142, -122.485262988324) 1.461775e+13
## 5 -122.5099 37.77231 (37.7723131976814, -122.509895418239) 1.407342e+13
## 6 -122.4166 37.77391  (37.773907074489, -122.416578493475) 1.407343e+13

Crime Count General

How many different kinds of crimes and how frequent?

crimes = levels(SanFran$Category)
SanFran$Category = sapply(as.character(SanFran$Category), 
                           function(x) ifelse(grepl('THEFT',x),
                            'THEFT',x))
#SanFran$Category[which(SanFran$Category == 'VEHICLE THEFT')] = 'LARCENY/THEFT'
#SanFran$Category=factor(SanFran$Category,labels=unique(SanFran$Category))

I merged together the categories vehicle theft and larceny theft because, looking at some of the descriptions, I noticed that some vehicle theft have been categorized as larceny/theft, so it made no sense to keep the two separate (look at the output of head(SanFran) above).

Now I can check the most occurring crime categories

Cat = group_by(SanFran, Category)
CrimeCount = dplyr::summarise(Cat, count = n())
CrimeByCat=ggplot(data=CrimeCount, aes(x=CrimeCount$Category, y=CrimeCount$count))+
    geom_bar(aes(fill=CrimeCount$count),stat="identity") +coord_flip()
 CrimeByCat = CrimeByCat+
    scale_fill_distiller(name="Nr. of Crimes", palette = "Reds", breaks = pretty_breaks(n = 15),trans='reverse')
#    
CrimeByCat = CrimeByCat+ guides(fill=guide_legend(keywidth=0.2,keyheight=0.2,default.unit="inch"))
# 
CrimeByCat

The most frequent crimes are related to thefts, followed by non-criminal and other offenses, warrants, vehicle thefts. Missing people and assaults are also non-negligible.

Crime Count by neighborhood

Which is the district with the highest amount of crimes?

Let’s see how crimes are distributed on the surface of San Francisco

names(SanFran)[which(names(SanFran)=='X')] = 'Longitude'
names(SanFran)[which(names(SanFran)=='Y')] = 'Latitude'
xrange = max(SanFran$Longitude)-min(SanFran$Longitude)
yrange =  max(SanFran$Latitude)-min(SanFran$Latitude)
xlim = c(min(SanFran$Longitude),max(SanFran$Longitude))
ylim = c(min(SanFran$Latitude),max(SanFran$Latitude))
crimes_per_d = ddply(SanFran,.(PdDistrict),nrow)
names(crimes_per_d)[2] = 'TotalNumCrimes'
SanFranmap = ddply(SanFran,.(PdDistrict),summarize, 
                   meanLat = round(mean(Latitude),2), 
                   meanLong = round(mean(Longitude),2))
SanFranmap['TotNumCrimes'] = crimes_per_d['TotalNumCrimes']

set.seed(8000)
#http://www.r-bloggers.com/mapping-with-ggplot-create-a-nice-choropleth-map-in-r/
#https://data.sfgov.org/Public-Safety/Historic-Police-Districts/embj-38bg
PdDistricts.shp <- readShapeSpatial("./Historic\ Police\ Districts//geo_export_061708fa-db2a-48c9-8e51-f2548a086820.shp")
v = PdDistricts.shp$objectid
names(v) = PdDistricts.shp$district

SanFranmap$id = sapply(SanFranmap$PdDistrict, function(x) v[as.character(x)])
PdDistricts.f = fortify(PdDistricts.shp, region = "objectid")
merge.shp.coef<-merge(PdDistricts.f, SanFranmap, by="id", all.x=TRUE)
final.plot<-merge.shp.coef[order(merge.shp.coef$order), ] 

SanFranmap$Latrev = SanFranmap$meanLat
SanFranmap$Longrev = SanFranmap$meanLong
SanFranmap$Latrev[8] = 37.777 
SanFranmap$Longrev[8] = -122.395
SanFranmap$Latrev[10] = 37.785
g = ggplot() +
     geom_polygon(data = final.plot, 
               aes(x = long, y = lat, group = group, fill = TotNumCrimes), 
               color = "black", size = 0.25) + 
  coord_map() +
  scale_fill_distiller(name="Nr. of Crimes", palette = "Reds", breaks = pretty_breaks(n = 5),trans='reverse')+
  theme_nothing(legend = TRUE)+
  labs(title="Total nr. of crimes per Police District: San Francisco")+
  geom_text(data=SanFranmap, aes(Longrev, Latrev, label = PdDistrict), size=5, fontface="bold")
g

The district with the highest number of crimes is Southern and in general crimes peak on the Eastern coastal districts, decreasing as one goes towards the West

Do kinds of crime vary by district?

Top 5 most occurring crimes by district

CrimeCount=CrimeCount[ order(-CrimeCount[,2]), ]
Top5 = as.character(CrimeCount$Category[1:5])
SanFran$Top5 = sapply(SanFran$Category, function(x) ifelse (as.character(x) %in% Top5,as.character(x),'Others'))
bycat = group_by(SanFran,Top5,PdDistrict)
sumc = dplyr::summarise(bycat,count = n())
ggplot(sumc, aes(x = PdDistrict, y = count, fill = Top5)) +
  geom_bar(stat = 'identity', position = 'fill', colour = 'black') +
  #facet_wrap(~PdDistrict) +
  coord_flip() +
  labs(y = 'Percentage of crimes', 
       x = 'Police District',
       title = 'Top 5 most occurring crimes  by District') 

In Southern, Central and Northern district the relative majority of thefts is more pronounced than in the other districts where the crime-type distribution seems more diversified with Mission, Tenderloin and Bayview being the most diversified with the lowest percentage of thefts.

Thefts by district and hour of day

SanFran$Date = as.POSIXct(SanFran$Date, format="%m/%d/%Y")
SanFran$Month = month(SanFran$Date)
SanFran$Day = day(SanFran$Date)
SanFran$Time = as.POSIXct(SanFran$Time, format="%H:%M")
SanFran$Hour = hour(SanFran$Time)

subs = SanFran[which(SanFran$Category=='THEFT'),]
by_cat = group_by(subs,PdDistrict,Hour)
sumc = dplyr::summarise(by_cat,count = n())

ggplot(sumc, aes(x = PdDistrict, y = Hour)) + 
    geom_tile(aes(fill = count)) + 
    scale_fill_distiller(name="Nr. of Thefts", palette = "Reds", breaks = pretty_breaks(n = 5),trans='reverse')+
    theme(axis.title.y = element_blank()) + theme_light(base_size = 10) + 
    theme(plot.title = element_text(size = 16)) + 
    ggtitle("Theft count by District and hour") + 
    theme(axis.text.x = element_text(angle = 45,size = 8, vjust = 0.5)) 

We see that, as already mentioned, the Southern, Central and Northern district exhibit a much more pronounced theft pattern. Thefts seem more likely to occurr in the afternoon-evening alotough, in the Southern district, one should watch out all day long except in the earliest hours of the day