Instructions

Warning: Do not copy and paste any code I give out here. You MUST write them up. If you copy and paste code from here to your RStudio, you will receive errors.

In Chapter 13 we explored how to use “mashup” data to create a map and put additional data “on top of” the map. In this assignment, we will do that, but with one additional requirement to “zoom” into the region of the United States where the data is of interest.

First, read in the dataset Police_calls_for_service.csv (in the project’s data folder). The column show the description of crime, the address of the crime, Dispatched time, and the type of Report. As you can guess from the title of the data file, the focus of the dataset is crimes around the Tampa, FL area.

For this assignment, you need to create two different, but related, maps: A map with “points” for each of the crimes, and a “density map” showing the same information.

Install the “ggplot2” and “ggmap” packages as needed, and load the two packages in the setup code chunk below.


# Add your library below.
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
library(ggmap)
## Warning: package 'ggmap' was built under R version 4.4.3

Step 1 - A map with “points” for each of the crimes

Step 1.1 - Read the data

  1. Read in Police_calls_for_service.csv and save it as an object.
  2. Investigate the data structure.
# Write your code below.
police_calls <- read.csv("Police_calls_for_service.csv", stringsAsFactors = FALSE)
str(police_calls)
## 'data.frame':    5446 obs. of  5 variables:
##  $ Dispatched : chr  "1/17/2023 15:14" "1/17/2023 15:43" "1/17/2023 15:04" "1/17/2023 15:36" ...
##  $ Description: chr  "SUSPICIOUS VEHICLE" "HOLDING PERSON" "VEHICLE STOP/TRAFFIC" "INFORMATION" ...
##  $ Address    : chr  "2400 BLOCK W AZEELE ST" "5000 BLOCK E BUSCH BLVD" "N 39TH ST / E LAKE AVE" "1000 BLOCK E NORTH BAY ST" ...
##  $ Grid       : int  160 24 99 83 222 83 124 53 29 99 ...
##  $ Report     : int  24599 24594 24591 24593 24592 24586 24584 24583 24582 24588 ...

Step 1.2 - Get your Google API Key

  1. You need a Google API key for the next step, which uses the geocode() function. Google API requires you to register your credit card information.

Step 1.3 - Get Latitudes and Longitudes

  1. Get latitudes and longitudes for all address in the crime dataset and store them in a new column using the geocode() function.
  2. Make sure the new dataframe includes lon and lat columns.
  3. Investigate the structure.

It should look something like this (details could be differ from your data):

Step 1.3 Environment
Step 1.3 Environment
# Write your code below.

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidygeocoder)
## Warning: package 'tidygeocoder' was built under R version 4.4.3
## 
## Attaching package: 'tidygeocoder'
## The following object is masked from 'package:ggmap':
## 
##     geocode
# Read your data
police_calls <- read.csv("Police_calls_for_service.csv", stringsAsFactors = FALSE)

# Prepare address column for geocoding
police_calls <- police_calls %>%
  mutate(address_clean = ifelse(grepl("Tampa", Address, ignore.case = TRUE),
                                Address,
                                paste(Address, "Tampa, FL"))) %>%
  mutate(address_clean = gsub("BLOCK|BLK|\\.\\.\\.", "", address_clean)) %>%
  mutate(address_clean = trimws(address_clean))

# IMPORTANT: Set correct environment variable name for Google API key before geocoding
Sys.setenv(GOOGLEGEOCODE_API_KEY = "AIzaSyCDNcQrWtZu3e0v4i6v_Du_YfKy3NFv-UQ")

# Perform geocoding
police_calls_geo <- geocode(
  police_calls,
  address = address_clean,
  method = "google",
  lat = "lat",
  long = "lon",
  limit = 1,
  return_input = TRUE,
  progress_bar = TRUE
)
## Passing 2,972 addresses to the Google single address geocoder
# Display structure of geocoded data
str(police_calls_geo)
## tibble [5,446 Ă— 8] (S3: tbl_df/tbl/data.frame)
##  $ Dispatched   : chr [1:5446] "1/17/2023 15:14" "1/17/2023 15:43" "1/17/2023 15:04" "1/17/2023 15:36" ...
##  $ Description  : chr [1:5446] "SUSPICIOUS VEHICLE" "HOLDING PERSON" "VEHICLE STOP/TRAFFIC" "INFORMATION" ...
##  $ Address      : chr [1:5446] "2400 BLOCK W AZEELE ST" "5000 BLOCK E BUSCH BLVD" "N 39TH ST / E LAKE AVE" "1000 BLOCK E NORTH BAY ST" ...
##  $ Grid         : int [1:5446] 160 24 99 83 222 83 124 53 29 99 ...
##  $ Report       : int [1:5446] 24599 24594 24591 24593 24592 24586 24584 24583 24582 24588 ...
##  $ address_clean: chr [1:5446] "2400  W AZEELE ST Tampa, FL" "5000  E BUSCH BLVD Tampa, FL" "N 39TH ST / E LAKE AVE Tampa, FL" "1000  E NORTH BAY ST Tampa, FL" ...
##  $ lat          : num [1:5446] 27.9 28 28 28 28.1 ...
##  $ lon          : num [1:5446] -82.5 -82.4 -82.4 -82.4 -82.4 ...

Step 1.4 - Create simpleMap object

Use the following code to create an object called simpleMap:

#get latitude and longtitude for USF
tampa <-geocode ("usf, tampa, fl")
tampa

# obtain maps from multiple sources and zoom into the region around tampaacuse university
tampa.map <-get_map(location=tampa, zoom=11)

# generate map and sore it in "simpleMap"
simpleMap <- ggmap(tampa.map)
# plot the map
simpleMap
# Write your code below.

library(ggmap)

# Register the Google API key if not already done
register_google(key = "AIzaSyCDNcQrWtZu3e0v4i6v_Du_YfKy3NFv-UQ")

# Manually specify the approximate lon/lat coordinates of USF Tampa
usf_coords <- c(lon = -82.4380, lat = 27.9428)

# Obtain Google map centered at the specified coordinates with zoom level 11
tampa_map <- get_map(location = usf_coords, zoom = 11, source = "google", maptype = "roadmap")
## ℹ <https://maps.googleapis.com/maps/api/staticmap?center=27.9428,-82.438&zoom=11&size=640x640&scale=2&maptype=roadmap&language=en-EN&key=xxx-UQ>
# Create the ggmap object from fetched map tiles
simpleMap <- ggmap(tampa_map)

# Plot the simpleMap to visualize
print(simpleMap)

Step 1.5 - Create Tampa_crimemape

Create an object called Tampa_crimemap based on simpleMap, where each point represents one crime.

It should look like this:

Step 1.5 Map
Step 1.5 Map
# Write your code below.

library(ggplot2)

# Overlay crime points on simpleMap base map
Tampa_crimemap <- simpleMap +
  geom_point(
    data = police_calls_geo,      # your geocoded crime dataset
    aes(x = lon, y = lat),        # longitude and latitude columns
    alpha = 0.3,                  # transparency for overlapping points
    color = "red",                # color of crime points
    size = 1                      # size of each point
  ) +
  labs(title = "Crime Locations in Tampa Around USF") +
  theme_minimal()

# Plot the crime map with crime points
print(Tampa_crimemap)
## Warning: Removed 126 rows containing missing values or values outside the scale range
## (`geom_point()`).


Step 2 - A “density map” showing the same information.

Use the geom_density2d() function. See the documentation as well as the ggplot cheatsheet to acquire more information on this.

The plot should look like this:

Step 2 Map
Step 2 Map
# Write your code below.

library(ggplot2)

# Density map showing crime density contours over simpleMap base
Tampa_crimedensity_map <- simpleMap +
  geom_density2d(
    data = police_calls_geo,    # geocoded crime data frame
    aes(x = lon, y = lat),      # longitude and latitude columns
    size = 0.3                  # line thickness for density contours
  ) +
  labs(title = "Crime Density Contours in Tampa Around USF") +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Plot the density map
print(Tampa_crimedensity_map)
## Warning: Removed 126 rows containing non-finite outside the scale range
## (`stat_density2d()`).