Our dataset contains all parking citations issued by Montgomery County Department of Transportation (MCDOT) enforcement personnel in the Montgomery County Parking Lot Districts and Transportation Management Districts of Bethesda, Montgomery Hills, Silver Spring, Wheaton, North Bethesda, Friendship Heights, Greater Seneca Science Center and the Residential Permit Parking areas. This includes all on-street metered parking, public surface lots and public garages. The parking citations list the following: date/time, location, vehicle information, and description of the violation.
Data Provider: MCG ESB Service, Montgomery County, MD
Some citations are issued using handheld electronic ticket writing equipment and are downloaded within just a few days after being issued. Handwritten citations can take several weeks to be entered into the parking citation system.
Integrity of parking citations can be compromised by simple typographical errors, misidentified vehicle or contains a wrong location. For the purposes of this analysis we shall assume each record in the dataset is factual. ****** # EXPLORATORY ANALYSIS This exploratory analysis will use R as the tool to visualize and transform the data in a systematic way. With any dataset there will always be a need to investigate the quality the data.
# Start with clean environment
rm(list=ls());
# Libraries
library(dygraphs); # Interface to JavaScript charting library
library(xts); # To make the convertion data-frame/xts format
library(tidyverse);# Collection of R packages designed for data science
library(lubridate);# Makes it easier to work with dates and times
library(leaflet); # Interface to JS library to make interactive web maps
library(rgdal); # Geospatial Data Abstraction Library
# Global Variables
infile_raw <- "./data/DOT_Parking_Tickets.csv";
infile_geo <- "./data/geocoded.csv";
infile_json <- "./data/json/gz_2010_us_050_00_20m.json";
latBox <- c( 38.9, 39.4); # ~Latitudal limits of Montogomery County
lonBox <- c(-76.9, -77.4); # ~Longitudal limits of Montogomery County
Since the dataset were based on hand written tickets issued by law enforcement and then transcribed into a dataset, there are inconsistencies in the entries (especially when the violation is not one the violations that is pre-populated on the parking ticket form), and missing data. As we go through the data cleaning process we will determine if the data meets our expectations or not.
## Load csv data set
df.raw <- read.csv(infile_raw);
str(df.raw);
'data.frame': 145949 obs. of 14 variables:
$ Ticket.Number : int 403678144 402943262 403643236 403454660 402841876 403384332 402419721 403662490 402735911 403345353 ...
$ Date.Time : Factor w/ 106861 levels "01/03/2017 01:04:00 PM",..: 40161 95629 37133 24988 86985 19703 58745 38018 79596 17382 ...
$ Parking.Division : int 3 3 2 2 2 2 9 2 2 2 ...
$ Ticket.Location : Factor w/ 5296 levels "","1 GREENLANE CT",..: 4294 5228 5217 2158 2434 5212 2794 2272 3568 1986 ...
$ Meter : Factor w/ 10799 levels "","^()!","0",..: NA 6273 7479 410 622 7000 1 456 10513 648 ...
$ Violation.Code : int 35 50 50 50 50 50 54 50 35 50 ...
$ Violation.Description: Factor w/ 40 levels "","BLK ANTHR VEH - STRE",..: 37 6 6 6 6 6 33 6 37 6 ...
$ Plate.Year : Factor w/ 36 levels "","00","0000",..: 22 22 24 22 1 22 21 NA 1 23 ...
$ Vehicle.Make : Factor w/ 78 levels "","ACUR","ALFA",..: 28 21 51 12 68 39 17 71 26 24 ...
$ Plate.Month : int 7 1 3 11 NA 6 12 NA NA 5 ...
$ Vehicle.Type : Factor w/ 16 levels "","2D","4D","BT",..: 3 3 3 16 3 3 16 3 11 16 ...
$ Vehicle.Color : Factor w/ 18 levels "","BG","BK","BL",..: 3 3 3 17 8 3 16 15 3 17 ...
$ Remarks : Factor w/ 14607 levels "",".",". -NO YEAR STICKER DISPLAYED",..: 14040 1502 1502 314 1502 1502 13733 314 11782 1502 ...
$ Issuing.Agency : Factor w/ 1 level "DOT": 1 1 1 1 1 1 1 1 1 1 ...
Elminated three varables: Meter, Issuing.Agency, and Ticket.Number To do data cleaning, you’ll need to deploy all the tools of EDA: visualisation, transformation, and modelling.
## Create a new dataset without missing data
df <- df.raw; # Copy original
# df$Meter <- NULL; # Remove variable
df$Issuing.Agency <- NULL; # Remove variable
df$Ticket.Number <- NULL; # Remove variable
df$Date.Time <- mdy_hms(df$Date.Time); # Convert to ts
df$Ticket.Location <- as.character(df$Ticket.Location); # Convert to string
df$Ticket.Date <- date(df$Date.Time); # Derive Date
df$Ticket.Hour <- hour(df$Date.Time); # Derive Hour
df$Ticket.Day <- wday(df$Date.Time, label=T, abbr=T); # Derive Day of week
df$Ticket.Month <- month(df$Date.Time,label=T, abbr=T); # Derive Month
df$Ticket.Year <- year(df$Date.Time); # Derive Year
df$Parking.Division<- factor(case_when(
is.na(df.raw$Parking.Division) ~ "??",
TRUE ~ as.character(df.raw$Parking.Division)
));
df$Violation.Code <- factor(case_when(
is.na(df.raw$Violation.Code) ~ as.integer(0),
TRUE ~ as.integer(df.raw$Violation.Code)
));
df$Violation.Description <- factor(case_when(
is.na(df.raw$Violation.Description) ~ "No description",
df.raw$Violation.Description=="UNREG VEH OFF STREET" ~ "UNREG VEH OFF STREET", # 02
df.raw$Violation.Description=="PRK/STND/STOP RUSH H" ~ "PARK/STAND/STOP - RUSH HOUR", # 17
df.raw$Violation.Description=="WITHIN 15 FT HYDRANT" ~ "WITHIN 15 FEET OF FIRE HYDRANT", # 19
df.raw$Violation.Description=="NO STND/PRK FIRE LN" ~ "NO STND/PRK FIRE LN", # 25
df.raw$Violation.Description=="NPAT - ON STREET" ~ "NPAT - ON STREET", # 34
df.raw$Violation.Description=="OFFICIAL SIGN OFF ST" ~ "OFFICIAL SIGN OFF ST", # 36
df.raw$Violation.Description=="HANDICAP PKG AREA" ~ "HANDICAP AREA", # 43
df.raw$Violation.Description=="EXPIRED PRKG METER" ~ "EXPIRED METER", # 50
df.raw$Violation.Description=="RES PRKG PERMIT ONLY" ~ "RESIDENTIAL PERMIT ONLY", # 43
df.raw$Violation.Description=="NT IN PRK SPC OFF ST" ~ "NOT WITHIN SPACE - OFF STREET", # 38
df.raw$Violation.Description=="COMM. VEH/BUS/REC IN RESID. ZONE" ~ "COMM. VEH/BUS/REC IN RESID. ZONE", # 04
df.raw$Violation.Description=="PARKED WITHIN 35 FEET OF INTERSECTION" ~ "WITHIN 35 FEET OF INTERSECTION", # 06
df.raw$Violation.Description=="WTHIN 5 FT DRIVEWAY" ~ "WITHIN 5 FEET OF DRIVEWAY - ON STREET",# 08
df.raw$Violation.Description=="OFFICIAL SIGN OFF ST" ~ "OFFICIAL SIGN OFF STREET", # ??
df.raw$Violation.Description=="OVR 24 HRS OFF STREE" ~ "OVER 24 HRS OFF STREET", # ??
df.raw$Violation.Description=="UNREGISTERED VEH ON STR" ~ "UNREGISTERED VEHICLE ON STREET", # ??
df.raw$Violation.Description=="WITHIN 20 FT CROSSWK" ~ "WITHIN 20 FT CROSSWALK", # ??
df.raw$Violation.Description=="OVERTM PRKG - STREET" ~ "OVERTIME PARKING - STREET", # ??
df.raw$Violation.Description=="UNREG VEH OFF STREET" ~ "UNREGISTERED VEHICLE OFF STREET",# ??
df.raw$Violation.Description=="NO STANDING - ON STR" ~ "NO STANDING - ON STREET", # ??
df.raw$Violation.Description=="DOUBLE PARKED - STRE" ~ "DOUBLE PARKED - STREET", # ??
df.raw$Violation.Description=="IMPEDING TRAFF/SAFET" ~ "IMPEDING TRAFFIC/SAFETY", # ??
df.raw$Violation.Description=="PARK MORE 1 FT CURB" ~ "PARK MORE THAN 1 FEET FROM CURB",# ??
df.raw$Violation.Description=="VIOLATION OFFICIAL SIGN ON STREET" ~ "VIOLATION OFFICIAL SIGN ON STREET", # ??
TRUE ~ as.character(df.raw$Violation.Code)
));
df$Plate.Month <- factor(case_when(
df.raw$Plate.Month==1 ~ "JAN", df.raw$Plate.Month==2 ~ "FEB",
df.raw$Plate.Month==3 ~ "MAR", df.raw$Plate.Month==4 ~ "APR",
df.raw$Plate.Month==5 ~ "MAY", df.raw$Plate.Month==6 ~ "JUN",
df.raw$Plate.Month==7 ~ "JUL", df.raw$Plate.Month==8 ~ "AUG",
df.raw$Plate.Month==9 ~ "SEP", df.raw$Plate.Month==10 ~ "OCT",
df.raw$Plate.Month==11 ~ "NOV", df.raw$Plate.Month==12 ~ "DEC",
TRUE ~ "???"
));
df$Plate.Year <- factor(case_when(
df.raw$Plate.Year=="00" | df.raw$Plate.Year=="" | df.raw$Plate.Year=="3540" |
df.raw$Plate.Year=="NAA" | is.na(df.raw$Plate.Year) ~ "????",
df.raw$Plate.Year=="207" ~ "2007",
df.raw$Plate.Year=="9" ~ "2009",
df.raw$Plate.Year=="2020" ~ "2010",
df.raw$Plate.Year=="2021" ~ "2011",
df.raw$Plate.Year=="2022" ~ "2012",
df.raw$Plate.Year=="2023" ~ "2013",
df.raw$Plate.Year=="2024" ~ "2014",
df.raw$Plate.Year=="0216" ~ "2016",
df.raw$Plate.Year=="17" | df.raw$Plate.Year=="0217" | df.raw$Plate.Year=="1017" ~ "2017",
df.raw$Plate.Year=="1018" | df.raw$Plate.Year=="2118" | df.raw$Plate.Year=="2028" ~ "2018",
df.raw$Plate.Year=="5019" | df.raw$Plate.Year=="0219" ~ "2019",
TRUE ~ as.character(df.raw$Plate.Year)
));
df$Remarks <- as.factor(case_when(
df.raw$Remarks=="1 HR PARKING." ~ "01 HR PARKING",
df.raw$Remarks=="1 HR PARKING" ~ "01 HR PARKING",
df.raw$Remarks=="2 HR PARKING" ~ "02 HR PARKING",
df.raw$Remarks=="3 HR PARKING" ~ "03 HR PARKING",
df.raw$Remarks=="4 HR PARKING" ~ "04 HR PARKING",
df.raw$Remarks=="9 HR PARKING" ~ "09 HR PARKING",
df.raw$Remarks=="9 HR PARKING NO PERMIT" ~ "09 HR PARKING-NO PERMIT",
df.raw$Remarks=="9 HR PARKING - NO PERMIT" ~ "09 HR PARKING-NO PERMIT",
df.raw$Remarks=="9 HR PARKING/NO PERMIT" ~ "09 HR PARKING-NO PERMIT",
df.raw$Remarks=="9 HR PARKING/NO PERIT" ~ "09 HR PARKING-NO PERMIT",
df.raw$Remarks=="9 HR PARKING/NO VISIBLE PERMIT" ~ "09 HR PARKING-NO PERMIT",
df.raw$Remarks=="9 HR PARKING NO PERMIT INSIDE" ~ "09 HR PARKING-NO PERMIT",
df.raw$Remarks=="9 HR PARKING-NO PERMIT DISPLAYED" ~ "09 HR PARKING-NO PERMIT",
df.raw$Remarks=="10HR PARKING NO PERMIT" ~ "10 HR PARKING-NO PERMIT",
df.raw$Remarks=="12 HR PARKING/NO PERMIT" ~ "12 HR PARKING-NO PERMIT",
df.raw$Remarks=="12 HR PARKING NO PERMIT" ~ "12 HR PARKING-NO PERMIT",
df.raw$Remarks=="12 HR PARKING NO PERMIT" ~ "12 HR PARKING-NO PERMIT",
df.raw$Remarks=="12 HR PARKING - NO PERMIT" ~ "12 HR PARKING-NO PERMIT",
df.raw$Remarks=="12 HR PARKING NO PERMIT INSIDE" ~ "12 HR PARKING-NO PERMIT",
df.raw$Remarks=="15 HR PARKING NO PERMIT" ~ "15 HR PARKING-NO PERMIT",
df.raw$Remarks=="15 HR PARKING NO PERMIT" ~ "15 HR PARKING-NO PERMIT",
df.raw$Remarks=="15 HR PARKING/NO PERMIT" ~ "15 HR PARKING-NO PERMIT",
TRUE ~ as.character(df.raw$Remarks)
));
df$Vehicle.Color <- as.factor(case_when(
df.raw$Vehicle.Color=="AL" ~ "Aluminum",
df.raw$Vehicle.Color=="AM" ~ "Amber",
df.raw$Vehicle.Color=="BG" ~ "Beige",
df.raw$Vehicle.Color=="BK" ~ "Black",
df.raw$Vehicle.Color=="BL" | df.raw$Vehicle.Color=="BU" ~ "Blue",
df.raw$Vehicle.Color=="BN" | df.raw$Vehicle.Color=="BR" ~ "Brown",
df.raw$Vehicle.Color=="BZ" ~ "Bronze",
df.raw$Vehicle.Color=="CH" ~ "Charcoal",
df.raw$Vehicle.Color=="CL" ~ "Clear",
df.raw$Vehicle.Color=="DK" ~ "Dark",
df.raw$Vehicle.Color=="GD" | df.raw$Vehicle.Color=="GO" ~ "Gold",
df.raw$Vehicle.Color=="GN" | df.raw$Vehicle.Color=="GR" ~ "Green",
df.raw$Vehicle.Color=="GY" ~ "Gray",
df.raw$Vehicle.Color=="GT" ~ "Granite",
df.raw$Vehicle.Color=="IV" ~ "Ivory",
df.raw$Vehicle.Color=="LT" ~ "Light",
df.raw$Vehicle.Color=="MA" ~ "Magenta",
df.raw$Vehicle.Color=="MC" ~ "MC",
df.raw$Vehicle.Color=="OL" ~ "Olive",
df.raw$Vehicle.Color=="OP" ~ "Opaque",
df.raw$Vehicle.Color=="OR" | df.raw$Vehicle.Color=="OR" ~ "Orange",
df.raw$Vehicle.Color=="PI" | df.raw$Vehicle.Color=="PK" ~ "Pink",
df.raw$Vehicle.Color=="PU" ~ "Purple",
df.raw$Vehicle.Color=="RD" | df.raw$Vehicle.Color=="RE" ~ "Red",
df.raw$Vehicle.Color=="SI" ~ "Silver",
df.raw$Vehicle.Color=="SM" ~ "Smoke",
df.raw$Vehicle.Color=="TN" ~ "Tan",
df.raw$Vehicle.Color=="TK" | df.raw$Vehicle.Color=="TQ" ~ "Turquoise",
df.raw$Vehicle.Color=="VT" ~ "Violet",
df.raw$Vehicle.Color=="WH" | df.raw$Vehicle.Color=="WT" ~ "White",
df.raw$Vehicle.Color=="YE" | df.raw$Vehicle.Color=="YL" ~ "Yellow",
TRUE ~ as.character(df.raw$Vehicle.Color)
));
df$Meter <- as.factor(case_when(
is.na(df.raw$Meter) ~ as.character("???"),
df.raw$Meter=="N/A" ~ as.character("???"),
df.raw$Meter=="^()!" ~ as.character("???"),
TRUE ~ as.character(df.raw$Meter)
));
df <- na.omit(df);
summary(df, maxsum=10);
Date.Time Parking.Division Ticket.Location Meter
Min. :2016-07-01 06:14:00 ??: 4 Length:145931 : 25127
1st Qu.:2016-09-30 13:11:00 0 : 1 Class :character ??? : 4761
Median :2017-01-09 07:59:00 10: 996 Mode :character 1102805: 136
Mean :2017-01-03 14:05:16 2 :73085 1107302: 136
3rd Qu.:2017-04-07 08:34:30 3 :42944 1101211: 135
Max. :2017-06-29 21:45:00 4 :10909 1101207: 134
5 : 719 1101209: 133
8 : 6413 1102803: 128
9 :10860 1101208: 122
(Other):115119
Violation.Code Violation.Description Plate.Year
50 :109115 EXPIRED METER :109115 2017 :63866
54 : 6975 RESIDENTIAL PERMIT ONLY : 6975 2018 :49413
17 : 4308 PARK/STAND/STOP - RUSH HOUR : 4308 2016 :15441
7 : 4215 OVERTIME PARKING - STREET : 4215 ???? : 9170
35 : 4136 VIOLATION OFFICIAL SIGN ON STREET: 4136 2019 : 6721
34 : 3980 NPAT - ON STREET : 3980 2015 : 638
2 : 3130 UNREGISTERED VEHICLE ON STREET : 3130 2010 : 366
36 : 2957 OFFICIAL SIGN OFF ST : 2957 2014 : 131
42 : 2797 UNREG VEH OFF STREET : 2797 2011 : 51
(Other): 4318 (Other) : 4318 (Other): 134
Vehicle.Make Plate.Month Vehicle.Type Vehicle.Color
TOYT :22228 SEP :12543 4D :69658 Black :32413
HOND :19010 APR :12238 SU :42727 Gray :31789
FORD :13339 JUN :12117 VN :11616 White :28508
CHEV :10471 AUG :11817 2D : 8272 Silver :19275
NISS : 9665 JUL :11707 PU : 5815 Blue :13485
MERZ : 6238 MAR :11280 TK : 4127 Red : 7848
BMW : 5471 MAY :11275 SW : 1804 Green : 3525
HYUN : 5332 OCT :11139 CV : 1032 Magenta: 3187
VOLK : 4700 DEC :11038 TX : 356 Gold : 2780
(Other):49477 (Other):40777 (Other): 524 (Other): 3121
Remarks Ticket.Date Ticket.Hour Ticket.Day
02 HR PARKING :53008 Min. :2016-07-01 Min. : 5.00 Sun: 0
01 HR PARKING :26223 1st Qu.:2016-09-30 1st Qu.:11.00 Mon:17916
12 HR PARKING-NO PERMIT: 9614 Median :2017-01-09 Median :13.00 Tue:27913
03 HR PARKING : 4369 Mean :2017-01-03 Mean :13.29 Wed:28810
09 HR PARKING-NO PERMIT: 3524 3rd Qu.:2017-04-07 3rd Qu.:15.00 Thu:28857
15 HR PARKING-NO PERMIT: 2727 Max. :2017-06-29 Max. :22.00 Fri:29313
04 HR PARKING : 2333 Sat:13122
15 HR PARKING : 1167
EXPIRED TAGS : 1150
(Other) :41816
Ticket.Month Ticket.Year
May :13754 Min. :2016
Mar :13222 1st Qu.:2016
Aug :13184 Median :2017
Apr :12698 Mean :2017
Jan :12284 3rd Qu.:2017
Jun :12267 Max. :2017
Dec :12145
Jul :12132
Sep :11428
(Other):32817
| Column Name | Description | Type | Action Taken |
|---|---|---|---|
| Ticket.Number | Ticket Number | Plain Text | Deleted |
| Date.Time | Date/Time | Date & Time | Convert to POSIXct |
| Parking.Division | Parking Division | Plain Text | |
| Ticket.Location | Ticket Location | Plain Text | |
| Ticket.Date | Ticket Date | Date | Created from Date.Time |
| Ticket.Hour | Ticket hour of day | Factor | Created from Date.Time |
| Ticket.Day | Ticket day of week | Factor | Created from Date.Time |
| Ticket.Month | Ticket month of year | Factor | Created from Date.Time |
| Ticket.Year | Ticket year | Factor | Created from Date.Time |
| Meter | Meter | Plain Text | |
| Violation.Code | Violation Code | Plain Text | |
| Violation.Description | Violation Description | Plain Text | |
| Plate.Year | Plate Year | Plain Text | |
| Vehicle.Make | Vehicle Make | Plain Text | |
| Plate.Month | Plate Month | Plain Text | |
| Vehicle.Type | Vehicle Type | Plain Text | |
| Vehicle.Color | Vehicle Color | Plain Text | |
| Remarks | Remarks | Plain Text | |
| Issuing.Agency | Issuing Agency | Plain Text | Deleted |
# Load ticket locations previously geocoded
geocoded <- read.csv(infile_geo);
# Remove data that is way outside of the geographic bounds of Montgomery County
rlb <- (geocoded$lat>=latBox[1]) & (geocoded$lat<=latBox[2]);
ulb <- (geocoded$lon>=lonBox[2]) & (geocoded$lon<=lonBox[1]);
geocoded <- geocoded[rlb&ulb,];
rm(rlb, ulb); # Clean Up
head(geocoded);
tmp <- data.frame(table(df$Parking.Division)) %>% filter(Freq > 0);
p1 <- ggplot(data = df[df$Parking.Division %in% tmp$Var1,]) +
geom_bar(mapping = aes(x = Parking.Division)) +
ggtitle("Tickets issued by Division");
tmp <- data.frame(table(df$Parking.Division)) %>% filter(Freq > 0);
p2 <- ggplot(data = df[df$Parking.Division %in% tmp$Var1,]) +
geom_bar(mapping = aes(x = Parking.Division)) +
ggtitle("Tickets issued by Division");
multiplot(p1, p2, layout=matrix(c(1,2),nrow=1,byrow=TRUE)); # Display
rm(p1, p2, tmp); # cleanup
tmp <- data.frame(table(df$Vehicle.Make)) %>% filter(Freq > 2000);
p1 <- ggplot(data = df[df$Vehicle.Make %in% tmp$Var1,]) +
geom_bar(mapping = aes(x = Vehicle.Make)) +
ggtitle("Top Vehicle Makes");
tmp <- data.frame(table(df$Vehicle.Type)) #%>% filter(Freq > 50);
p2 <- ggplot(data = df[df$Vehicle.Type %in% tmp$Var1,]) +
geom_bar(mapping = aes(x = Vehicle.Type)) +
ggtitle("Top Vehicle Types");
tmp <- data.frame(table(df$Vehicle.Color)) #%>% filter(Freq > 50);
p3 <- ggplot(data = df[df$Vehicle.Color %in% tmp$Var1,]) +
geom_bar(mapping = aes(x = Vehicle.Color)) +
ggtitle("Top Vehicle Color");
multiplot(p3, p2, p1, layout=matrix(c(1,2,3),nrow=3,byrow=TRUE)); # Display
rm(p1, p2, p3, tmp); # cleanup
## Plots using ggplot (Histograms)
p1 <- ggplot(data = df) +
geom_bar(mapping = aes(x = Ticket.Month)) +
ggtitle("Tickets issued by month");
p2 <- ggplot(data = df) +
geom_bar(mapping = aes(x = Ticket.Hour)) +
ggtitle("Tickets issued by hour");
p3 <- ggplot(data = df) +
geom_bar(mapping = aes(x = Ticket.Day)) +
ggtitle("Tickets issued by day");
multiplot(p3, p2, p1, layout=matrix(c(1,2,3,3),nrow=2,byrow=TRUE)); # Display
rm(p1, p2, p3); # cleanup
## Plots using using dygraph (interactive Time series plot)
tmp <- as.data.frame(table(df$Ticket.Date));
don <- xts(x=tmp$Freq, order.by=ymd(tmp$Var1)); # Create the xts format
dygraph(don, main="Daily Tickets Issued (2016-2017)") %>%
dyOptions(labelsUTC= TRUE, fillGraph=TRUE, fillAlpha=0.1, drawGrid = TRUE, colors="#D8AE5A") %>%
dyLimit(max(tmp$Freq), label=paste0("MAX=",max(tmp$Freq)), labelLoc="left") %>%
dyLimit(mean(tmp$Freq),label=paste0("AVG=",as.integer(mean(tmp$Freq))),labelLoc="left") %>%
dyLimit(min(tmp$Freq), label=paste0("MIN=",min(tmp$Freq)), labelLoc="left") %>%
dyRangeSelector() %>%
dyCrosshair(direction = "both") %>%
dyHighlight(highlightCircleSize=5, highlightSeriesBackgroundAlpha=0.2, hideOnMouseOut=FALSE) %>%
dyRoller(rollPeriod = 1);
rm(tmp, don); # Clean up
leaflet(data=geocoded) %>%
addTiles() %>%
addRectangles(
lng1=lonBox[1], lat1=latBox[1],
lng2=lonBox[2], lat2=latBox[2],
fillColor = "transparent") %>%
addTopoJSON(topo,
weight = 1,
color = "#444444",
fill = TRUE) %>%
addProviderTiles(providers$Stamen.TonerLines,
options = providerTileOptions(opacity=0.35)) %>%
addProviderTiles(providers$Stamen.Toner) %>%
addCircleMarkers(~lon, ~lat,
color = ~getColor(freq),
stroke = TRUE,
fillOpacity = 0.25,
popup = ~as.character(addr));
rm(topo); # Clean Up