This project arose as a proof of concept for allowing easier access to publicly available crime data. In this project I use the ukpolice library to download the latest months reported crime and ASB data for Northern Ireland from data.police.uk. I then project this information to an interactive map using the MapView library.
pacman::p_load(mapview, ukpolice, sf)
data.police.uk will only allow downloads of a certain size (up to 10,000 records). This is below the number of expected reported crimes recorded in Northern Ireland in a month, so we will split the country into four regions and download the data for each separately.
Belfast has the highest concentration of crime, so we run the horizontal and vertical dividing lines through there to split that cluster into four. Each region therefore carries some of that load.
Firstly, we create dataframes containing the coordinates of the outside edge of each box. In this case, the boxes are simple rectangles so only four coordinates are needed. We do not need to return to the original coordinate as the ukpolice package will automatically join the last drawn point to the first to enclose the area.
# Generate poly-coordinate data frames
df1 <- data.frame(
lat = c(55.4, 54.65, 54.65, 55.4),
lng = c(-8.2, -8.2, -5.95, -5.95)
)
df2 <- data.frame(
lat = c(54.65, 54.0, 54.0, 54.65),
lng = c(-8.2, -8.2, -5.95, -5.95)
)
df3 <- data.frame(
lat = c(54.65, 54.0, 54.0, 54.65),
lng = c(-5.95, -5.95, -5.45, -5.45)
)
df4 <- data.frame(
lat = c(55.4, 54.65, 54.65, 55.4),
lng = c(-5.95, -5.95, -5.45, -5.45)
)
Once we have the bounding areas (polyframes) set, we can use the ukpolice::ukc_crime_poly() function to select all the records within that area and bring them into a dataframe. If we do not specify a month, then it will automatically default to the latest available month.
#download the data frames for each region
crimes_nw <- ukc_crime_poly(df1)
crimes_sw <- ukc_crime_poly(df2)
crimes_se<- ukc_crime_poly(df3)
crimes_ne <- ukc_crime_poly(df4)
When both dataframes are complete, we can combine them into one.
#combine the two dataframes
crimes_all <- rbind(crimes_nw, crimes_sw, crimes_se, crimes_ne)
By default, the latitude and longitude variables are given as character, so we have to coerce them to numeric.
#convert lat and long to numeric
crimes_all$latitude <- as.numeric(crimes_all$latitude)
crimes_all$longitude <- as.numeric(crimes_all$longitude)
We can then convert this dataframe into an sf object, which MapView can recognise. At this stage we can also append a coordinate reference system.
#convert dataframe to st object, and apply projection info
crimes_all <- st_as_sf(x = crimes_all,
coords = c("longitude", "latitude"),
crs = "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0")
The MapView function is then very simple. We can colour the points by a variable. In this case, we have coloured them by the crime category as given by data.police.uk. The “burst” command means that MapView will map each category as a separate layer, allowing you to show and hide different categories.
#produce map
mapview(crimes_all, xcol = "longitude", ycol = "latitude", zcol = "category", burst = TRUE, legend = FALSE)