library(tidyverse)
library(ggplot2)
library(plotly)

## Sequential complete mo/yr index for date plotting

index <- data.frame(yr = sort(rep(2019:2023, 12)),
                    mo = rep(1:12, 5)) %>%
  mutate(mon.yr = paste0(month.abb[mo], ".", yr),
         index.date = lubridate::ymd(paste0(yr, "-", mo, "-01")
         ))

start_mo <- 1

yrs <- as.numeric(lubridate::ymd(
  paste0(seq(min(index$yr), max(index$yr), 1), 
         "-", start_mo, "-01")))

# Key dates
today = Sys.Date()
date.start = as.Date("2019-01-01")
date.end = as.Date("2023-12-31")

date.reform = as.Date("2021-07-25") #90 days after end of session
date.modify = as.Date("2023-05-03") #threshold dropped to reasonable suspicion

# most of our data only run thru date.end, not date.rollback
date.rollback = as.Date("2024-06-05") #90 days after end of session, 3/7

# days in each period
days.pre = as.numeric(date.reform - date.start)
days.reformtot = as.numeric(date.end - date.reform)
days.reform = as.numeric(date.modify - date.reform)
days.modify = as.numeric(date.end - date.modify)

Introduction

This report examines how statewide pursuit policy changes influenced vehicle pursuits by law enforcement in WA State from 2019-2023.

Pursuits are unique among police tactics in their risk of collateral damage. Nationally, about one-third of pursuits lead to vehicular accidents, and a substantial fraction (over a third) of those injured or killed in these accidents are uninvolved bystanders, passengers and officers.

Here in Washington state, recent legislative changes provide an opportunity to observe whether pursuit policies adopted at the state level influence the number of pursuits conducted by local agencies.

Legislative history

Pursuit policy has been an active area of legislation in WA State, with parallels to the policy changes that took place in Milwaukee, WI. The changes define three policy periods in WA state useful for comparative analysis:

  • The “Pre-reform” period: prior to July 25, 2021

    Pursuit policies during this period were decentralized, and established by each agency, so there was a patchwork of different policies across the state. Some policies were quite restrictive, others left decisions to the discretion of officers. In this report, we look back to Jan 1, 2015 as the start of this observation period.

  • The “Reform” period: July 25, 2021 - May 3, 2023

    In 2021 the legislature enacted a statewide policy to provide a uniform standard and to improve public safety by reducing the growing number of people killed during these pursuits (House Bill 1054, effective July 25, 2021). At the time, pursuits were responsible for 10-20% of the fatalities from police activities each year. About half of those killed were passengers, officers or uninvolved bystanders.

    HB 1054 established a clear standard for balancing the danger posed to the public by the pursuit against the danger posed by a fleeing subject. It prioritized public safety: police are allowed to engage in pursuits when there is a well established threat to public safety – violent offenses (like carjackings, armed robberies), sex offenses, DUIs, and prison escapes – but not for misdemeanors or property crimes. It required that the evidence of the threat meets the “probable cause” standard – the same standard required to make an arrest. In effect the law said: If you don’t have enough evidence to arrest the person, then you can not justify the risk to public safety for this pursuit.

  • The “Modified” reform period.

    In 2023 the legislature modified the policy, lowering the standard of evidence required from probable cause to reasonable suspicion, adding vehicular and domestic assaults explicitly to the list of offenses eligible for pursuit, and removing the requirement for supervisory authorization. All other policy elements adopted during the 2021 session were retained. These changes took effect May 3, 2023.

  • The “Rollback” period: after June 5, 2024

    In response to a successful initiative campaign in 2023 to place a pursuit policy rollback on the November 2024 ballot, the legislature took the option of passing the initiative themselves in March 2024. The initiative removed all of the explicit public safety requirements for allowable pursuits, and replaced them with a simple discretionary requirement that “There is reasonable suspicion a person has violated the law” and “the threat to the safety of others and the safety risks of failing to apprehend or identify the person are considered to be greater than the safety risks of the vehicular pursuit under the circumstances.”

The full texts of the bills passed and the current law (RCW) on vehicle pursuits can be found in the Pursuit legislation section at the end of this report.

Data

The data presented in this report was obtained by submitting Public Disclosure Requests (PDR) to a sample of the roughly 275 law enforcement agencies in WA. The project was begun in late November 2023.

The data cover:

  • 166 law enforcement agencies

    Agencies were selected based on several criteria:

    • Accreditation – all WASPC and CALEA accredited law enforcement agencies
    • Signatories to pursuit policy rollback support letters
    • County Sheriff Offices (all)
    • Washington State Patrol
  • 4 years of data on pursuits: 2019-2023

We requested monthly counts (County Sheriff Offices and WSP) or incident-level data (all others) on the pursuits conducted by each agency from Jan 1, 2019 through December 31, 2023.

Pursuits by Agency

Aberdeen PD (Accredited, AWC)

load(here::here("AWC-Signatories", "Aberdeen - closed", "aberdeen.rda"))
jurisdiction <- "Aberdeen PD"
inci_df <- aberdeen.inci %>%
  mutate(incidate = date)
notes <- aberdeen.notes

Monthly pursuit time series

### Monthly pursuit count time series plot template

monthly_df <- inci_df %>% group_by(yr, mo) %>%
  count() %>%
  left_join(index, ., by = c("yr", "mo")) %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         numdate = as.numeric(index.date),
         period3 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform & index.date < date.modify ~ "Reform",
             index.date >= date.modify ~ "Post-modify"), 
           c("Pre-reform", "Reform", "Post-modify")),
         period2 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform ~ "Post-reform"), 
           c("Pre-reform", "Post-reform"))
  )

p <- ggplot(monthly_df, 
            aes(x = index.date, y = count)
       )  +
  
  geom_bar(aes(fill = factor(yr), text = paste0(mon.yr, ": ", count)),
           alpha=0.5, color="grey",
           stat="identity"
  ) +
  scale_fill_brewer(palette="Spectral") +
             
  geom_smooth(span = 0.5, linetype="dot", linewidth=.5) +
  
  # year boundaries
  geom_vline(xintercept = yrs, col="white", alpha=.5) +
  
  # dates
  geom_vline(xintercept = date.reform, col="darkgrey", alpha=.5) +
  geom_vline(xintercept = date.modify, col="darkgrey", alpha=.5) +
  
  annotate("text", x=(as.numeric(date.reform) - as.numeric(date.reform-date.start)/2),
           y=max(monthly_df$count)+0.5, 
           label="Pre-reform",
           size=3) +
  annotate("text", x=(as.numeric(date.reform) + as.numeric(date.modify-date.reform)/2),
           y=max(monthly_df$count)+0.5, 
           label="Reform",
           size=3) +
  annotate("text", x=(as.numeric(date.modify)+150), 
           y=max(monthly_df$count)+0.5, 
           label="Post-Modified",
           size=3) +
  
  
  geom_hline(yintercept = 0, col="grey") +
  
  labs(title = paste("Monthly pursuits:", jurisdiction, min(index$yr), "-", max(index$yr)),
       x = "Month.Year",
       y = "Number of pursuits",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") +
  
  scale_x_continuous(
    breaks = monthly_df$index.date[seq(1, nrow(monthly_df), 6)],
    label = monthly_df$mon.yr[seq(1, nrow(monthly_df), 6)]
  )  +
  
#  scale_y_continuous(limits = c(-2, max(monthly_df$count)+0.5), breaks = 0:max(monthly_df$count)) +
  scale_y_continuous(limits = c(-2, max(monthly_df$count, 10)+0.5), breaks = 0:max(monthly_df$count, 10)) +
  
  theme(axis.text.x = element_text(size=7, angle = 45, vjust = 0.5)) +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank())

ggplotly(p, tooltip = "text")

Pre-post plots

3 Policy periods

#### Avg monthly pursuit rate plot template: 3 Policy periods

period3_df <- inci_df %>% 
  mutate(period3 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform & incidate < date.modify ~ "Reform",
      incidate >= date.modify ~ "Post-modify"), 
    c("Pre-reform", "Reform", "Post-modify"))
  ) %>%
  group_by(period3) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
             period3 == "Pre-reform" ~ count/days.pre *30,
             period3 == "Reform" ~ count/days.reform *30,
             period3 == "Post-modify" ~ count/days.modify *30),
         days = case_when(
           period3 == "Pre-reform" ~ days.pre,
           period3 == "Reform" ~ days.reform,
           period3 == "Post-modify" ~ days.modify)
  )

p <- ggplot(period3_df, 
            aes(x = period3, y = ratepermo)
            )  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
               ),
           alpha=0.5, color="grey",
           stat="identity"
           ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate") 
  
ggplotly(p, tooltip = "text")

2 Policy periods

#### Avg monthly pursuit rate plot template: 2 Policy periods

period2_df <- inci_df %>% 
  mutate(period2 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform ~ "Post-reform"), 
    c("Pre-reform", "Post-reform"))
  ) %>%
  group_by(period2) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
           period2 == "Pre-reform" ~ count/days.pre *30,
           period2 == "Post-reform" ~ count/days.reform *30),
         days = case_when(
           period2 == "Pre-reform" ~ days.pre,
           period2 == "Post-reform" ~ days.reformtot)
  )

p <- ggplot(period2_df, 
            aes(x = period2, y = ratepermo)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
  ),
  alpha=0.5, color="grey",
  stat="identity"
  ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") 

ggplotly(p, tooltip = "text")

Zero pursuit month comparison

3 policy periods

#### Zero pursuit months plot template: 3 policy periods

zmonths3_df <- monthly_df %>%
  group_by(period3) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths3_df, 
            aes(x = period3, y = zmpct)
)  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
               ),
           alpha=0.5, color="grey",
           stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

2 policy periods

#### Zero pursuit months plot template: 2 policy periods

zmonths2_df <- monthly_df %>%
  group_by(period2) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths2_df, 
            aes(x = period2, y = zmpct)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
  ),
  alpha=0.5, color="grey",
  stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits:", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

Notes

### Notes/Info on data
print(notes)
## $format
## [1] "xls"
## 
## $uoa
## [1] "incident"
## 
## $range
## [1] "1/1/2019-12/31/2023"
## 
## $sample
## [1] "Accredited" "AWC"       
## 
## $limitations
## [1] "none known"

Anacortes PD (Accredited, AWC)

load(here::here("AWC-Signatories", "Anacortes - closed", "anacortes.rda"))
jurisdiction <- "Anacortes PD"
inci_df <- anacortes.inci %>%
  mutate(incidate = date)
notes <- anacortes.notes

Monthly pursuit time series

### Monthly pursuit count time series plot template

monthly_df <- inci_df %>% group_by(yr, mo) %>%
  count() %>%
  left_join(index, ., by = c("yr", "mo")) %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         numdate = as.numeric(index.date),
         period3 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform & index.date < date.modify ~ "Reform",
             index.date >= date.modify ~ "Post-modify"), 
           c("Pre-reform", "Reform", "Post-modify")),
         period2 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform ~ "Post-reform"), 
           c("Pre-reform", "Post-reform"))
  )

p <- ggplot(monthly_df, 
            aes(x = index.date, y = count)
       )  +
  
  geom_bar(aes(fill = factor(yr), text = paste0(mon.yr, ": ", count)),
           alpha=0.5, color="grey",
           stat="identity"
  ) +
  scale_fill_brewer(palette="Spectral") +
             
  geom_smooth(span = 0.5, linetype="dot", linewidth=.5) +
  
  # year boundaries
  geom_vline(xintercept = yrs, col="white", alpha=.5) +
  
  # dates
  geom_vline(xintercept = date.reform, col="darkgrey", alpha=.5) +
  geom_vline(xintercept = date.modify, col="darkgrey", alpha=.5) +
  
  annotate("text", x=(as.numeric(date.reform) - as.numeric(date.reform-date.start)/2),
           y=max(monthly_df$count)+0.5, 
           label="Pre-reform",
           size=3) +
  annotate("text", x=(as.numeric(date.reform) + as.numeric(date.modify-date.reform)/2),
           y=max(monthly_df$count)+0.5, 
           label="Reform",
           size=3) +
  annotate("text", x=(as.numeric(date.modify)+150), 
           y=max(monthly_df$count)+0.5, 
           label="Post-Modified",
           size=3) +
  
  
  geom_hline(yintercept = 0, col="grey") +
  
  labs(title = paste("Monthly pursuits:", jurisdiction, min(index$yr), "-", max(index$yr)),
       x = "Month.Year",
       y = "Number of pursuits",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") +
  
  scale_x_continuous(
    breaks = monthly_df$index.date[seq(1, nrow(monthly_df), 6)],
    label = monthly_df$mon.yr[seq(1, nrow(monthly_df), 6)]
  )  +
  
#  scale_y_continuous(limits = c(-2, max(monthly_df$count)+0.5), breaks = 0:max(monthly_df$count)) +
  scale_y_continuous(limits = c(-2, max(monthly_df$count, 10)+0.5), breaks = 0:max(monthly_df$count, 10)) +
  
  theme(axis.text.x = element_text(size=7, angle = 45, vjust = 0.5)) +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank())

ggplotly(p, tooltip = "text")

Pre-post plots

3 Policy periods

#### Avg monthly pursuit rate plot template: 3 Policy periods

period3_df <- inci_df %>% 
  mutate(period3 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform & incidate < date.modify ~ "Reform",
      incidate >= date.modify ~ "Post-modify"), 
    c("Pre-reform", "Reform", "Post-modify"))
  ) %>%
  group_by(period3) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
             period3 == "Pre-reform" ~ count/days.pre *30,
             period3 == "Reform" ~ count/days.reform *30,
             period3 == "Post-modify" ~ count/days.modify *30),
         days = case_when(
           period3 == "Pre-reform" ~ days.pre,
           period3 == "Reform" ~ days.reform,
           period3 == "Post-modify" ~ days.modify)
  )

p <- ggplot(period3_df, 
            aes(x = period3, y = ratepermo)
            )  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
               ),
           alpha=0.5, color="grey",
           stat="identity"
           ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate") 
  
ggplotly(p, tooltip = "text")

2 Policy periods

#### Avg monthly pursuit rate plot template: 2 Policy periods

period2_df <- inci_df %>% 
  mutate(period2 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform ~ "Post-reform"), 
    c("Pre-reform", "Post-reform"))
  ) %>%
  group_by(period2) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
           period2 == "Pre-reform" ~ count/days.pre *30,
           period2 == "Post-reform" ~ count/days.reform *30),
         days = case_when(
           period2 == "Pre-reform" ~ days.pre,
           period2 == "Post-reform" ~ days.reformtot)
  )

p <- ggplot(period2_df, 
            aes(x = period2, y = ratepermo)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
  ),
  alpha=0.5, color="grey",
  stat="identity"
  ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") 

ggplotly(p, tooltip = "text")

Zero pursuit month comparison

3 policy periods

#### Zero pursuit months plot template: 3 policy periods

zmonths3_df <- monthly_df %>%
  group_by(period3) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths3_df, 
            aes(x = period3, y = zmpct)
)  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
               ),
           alpha=0.5, color="grey",
           stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

2 policy periods

#### Zero pursuit months plot template: 2 policy periods

zmonths2_df <- monthly_df %>%
  group_by(period2) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths2_df, 
            aes(x = period2, y = zmpct)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
  ),
  alpha=0.5, color="grey",
  stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits:", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

Notes

### Notes/Info on data
print(notes)
## $format
## [1] "incident narratives"
## 
## $uoa
## [1] "incident"
## 
## $range
## [1] "1/1/2019-12/31/2023"
## 
## $sample
## [1] "Accredited" "AWC"       
## 
## $limitations
## [1] "none known"

Arlington PD (AWC)

load(here::here("AWC-Signatories", "Arlington", "arlington.rda"))
jurisdiction <- "Arlington PD"
inci_df <- arlington.inci %>%
  mutate(incidate = date)
notes <- arlington.notes

Monthly pursuit time series

### Monthly pursuit count time series plot template

monthly_df <- inci_df %>% group_by(yr, mo) %>%
  count() %>%
  left_join(index, ., by = c("yr", "mo")) %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         numdate = as.numeric(index.date),
         period3 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform & index.date < date.modify ~ "Reform",
             index.date >= date.modify ~ "Post-modify"), 
           c("Pre-reform", "Reform", "Post-modify")),
         period2 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform ~ "Post-reform"), 
           c("Pre-reform", "Post-reform"))
  )

p <- ggplot(monthly_df, 
            aes(x = index.date, y = count)
       )  +
  
  geom_bar(aes(fill = factor(yr), text = paste0(mon.yr, ": ", count)),
           alpha=0.5, color="grey",
           stat="identity"
  ) +
  scale_fill_brewer(palette="Spectral") +
             
  geom_smooth(span = 0.5, linetype="dot", linewidth=.5) +
  
  # year boundaries
  geom_vline(xintercept = yrs, col="white", alpha=.5) +
  
  # dates
  geom_vline(xintercept = date.reform, col="darkgrey", alpha=.5) +
  geom_vline(xintercept = date.modify, col="darkgrey", alpha=.5) +
  
  annotate("text", x=(as.numeric(date.reform) - as.numeric(date.reform-date.start)/2),
           y=max(monthly_df$count)+0.5, 
           label="Pre-reform",
           size=3) +
  annotate("text", x=(as.numeric(date.reform) + as.numeric(date.modify-date.reform)/2),
           y=max(monthly_df$count)+0.5, 
           label="Reform",
           size=3) +
  annotate("text", x=(as.numeric(date.modify)+150), 
           y=max(monthly_df$count)+0.5, 
           label="Post-Modified",
           size=3) +
  
  
  geom_hline(yintercept = 0, col="grey") +
  
  labs(title = paste("Monthly pursuits:", jurisdiction, min(index$yr), "-", max(index$yr)),
       x = "Month.Year",
       y = "Number of pursuits",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") +
  
  scale_x_continuous(
    breaks = monthly_df$index.date[seq(1, nrow(monthly_df), 6)],
    label = monthly_df$mon.yr[seq(1, nrow(monthly_df), 6)]
  )  +
  
#  scale_y_continuous(limits = c(-2, max(monthly_df$count)+0.5), breaks = 0:max(monthly_df$count)) +
  scale_y_continuous(limits = c(-2, max(monthly_df$count, 10)+0.5), breaks = 0:max(monthly_df$count, 10)) +
  
  theme(axis.text.x = element_text(size=7, angle = 45, vjust = 0.5)) +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank())

ggplotly(p, tooltip = "text")

Pre-post plots

3 Policy periods

#### Avg monthly pursuit rate plot template: 3 Policy periods

period3_df <- inci_df %>% 
  mutate(period3 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform & incidate < date.modify ~ "Reform",
      incidate >= date.modify ~ "Post-modify"), 
    c("Pre-reform", "Reform", "Post-modify"))
  ) %>%
  group_by(period3) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
             period3 == "Pre-reform" ~ count/days.pre *30,
             period3 == "Reform" ~ count/days.reform *30,
             period3 == "Post-modify" ~ count/days.modify *30),
         days = case_when(
           period3 == "Pre-reform" ~ days.pre,
           period3 == "Reform" ~ days.reform,
           period3 == "Post-modify" ~ days.modify)
  )

p <- ggplot(period3_df, 
            aes(x = period3, y = ratepermo)
            )  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
               ),
           alpha=0.5, color="grey",
           stat="identity"
           ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate") 
  
ggplotly(p, tooltip = "text")

2 Policy periods

#### Avg monthly pursuit rate plot template: 2 Policy periods

period2_df <- inci_df %>% 
  mutate(period2 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform ~ "Post-reform"), 
    c("Pre-reform", "Post-reform"))
  ) %>%
  group_by(period2) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
           period2 == "Pre-reform" ~ count/days.pre *30,
           period2 == "Post-reform" ~ count/days.reform *30),
         days = case_when(
           period2 == "Pre-reform" ~ days.pre,
           period2 == "Post-reform" ~ days.reformtot)
  )

p <- ggplot(period2_df, 
            aes(x = period2, y = ratepermo)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
  ),
  alpha=0.5, color="grey",
  stat="identity"
  ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") 

ggplotly(p, tooltip = "text")

Zero pursuit month comparison

3 policy periods

#### Zero pursuit months plot template: 3 policy periods

zmonths3_df <- monthly_df %>%
  group_by(period3) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths3_df, 
            aes(x = period3, y = zmpct)
)  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
               ),
           alpha=0.5, color="grey",
           stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

2 policy periods

#### Zero pursuit months plot template: 2 policy periods

zmonths2_df <- monthly_df %>%
  group_by(period2) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths2_df, 
            aes(x = period2, y = zmpct)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
  ),
  alpha=0.5, color="grey",
  stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits:", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

Notes

### Notes/Info on data
print(notes)
## $format
## [1] "RMS extract PDF"
## 
## $uoa
## [1] "incident"
## 
## $range
## [1] "1/1/2019-12/31/2023"
## 
## $sample
## [1] "AWC"
## 
## $limitations
## [1] "They sent a data file with info on pursuits from 2021-2023 that includes several additional VP relevant fields. These data are included in the RDA (arlington.xtra df), but not integrated into the incident df as the date range is incomplete. See correspondence for more details."

Auburn PD (AWC)

load(here::here("AWC-Signatories", "Auburn - closed", "auburn.rda"))
jurisdiction <- "Auburn PD"
inci_df <- auburn.inci %>%
  mutate(incidate = cdate) # see limitations
notes <- auburn.notes

Monthly pursuit time series

### Monthly pursuit count time series plot template

monthly_df <- inci_df %>% group_by(yr, mo) %>%
  count() %>%
  left_join(index, ., by = c("yr", "mo")) %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         numdate = as.numeric(index.date),
         period3 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform & index.date < date.modify ~ "Reform",
             index.date >= date.modify ~ "Post-modify"), 
           c("Pre-reform", "Reform", "Post-modify")),
         period2 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform ~ "Post-reform"), 
           c("Pre-reform", "Post-reform"))
  )

p <- ggplot(monthly_df, 
            aes(x = index.date, y = count)
       )  +
  
  geom_bar(aes(fill = factor(yr), text = paste0(mon.yr, ": ", count)),
           alpha=0.5, color="grey",
           stat="identity"
  ) +
  scale_fill_brewer(palette="Spectral") +
             
  geom_smooth(span = 0.5, linetype="dot", linewidth=.5) +
  
  # year boundaries
  geom_vline(xintercept = yrs, col="white", alpha=.5) +
  
  # dates
  geom_vline(xintercept = date.reform, col="darkgrey", alpha=.5) +
  geom_vline(xintercept = date.modify, col="darkgrey", alpha=.5) +
  
  annotate("text", x=(as.numeric(date.reform) - as.numeric(date.reform-date.start)/2),
           y=max(monthly_df$count)+0.5, 
           label="Pre-reform",
           size=3) +
  annotate("text", x=(as.numeric(date.reform) + as.numeric(date.modify-date.reform)/2),
           y=max(monthly_df$count)+0.5, 
           label="Reform",
           size=3) +
  annotate("text", x=(as.numeric(date.modify)+150), 
           y=max(monthly_df$count)+0.5, 
           label="Post-Modified",
           size=3) +
  
  
  geom_hline(yintercept = 0, col="grey") +
  
  labs(title = paste("Monthly pursuits:", jurisdiction, min(index$yr), "-", max(index$yr)),
       x = "Month.Year",
       y = "Number of pursuits",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") +
  
  scale_x_continuous(
    breaks = monthly_df$index.date[seq(1, nrow(monthly_df), 6)],
    label = monthly_df$mon.yr[seq(1, nrow(monthly_df), 6)]
  )  +
  
#  scale_y_continuous(limits = c(-2, max(monthly_df$count)+0.5), breaks = 0:max(monthly_df$count)) +
  scale_y_continuous(limits = c(-2, max(monthly_df$count, 10)+0.5), breaks = 0:max(monthly_df$count, 10)) +
  
  theme(axis.text.x = element_text(size=7, angle = 45, vjust = 0.5)) +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank())

ggplotly(p, tooltip = "text")

Pre-post plots

3 Policy periods

#### Avg monthly pursuit rate plot template: 3 Policy periods

period3_df <- inci_df %>% 
  mutate(period3 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform & incidate < date.modify ~ "Reform",
      incidate >= date.modify ~ "Post-modify"), 
    c("Pre-reform", "Reform", "Post-modify"))
  ) %>%
  group_by(period3) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
             period3 == "Pre-reform" ~ count/days.pre *30,
             period3 == "Reform" ~ count/days.reform *30,
             period3 == "Post-modify" ~ count/days.modify *30),
         days = case_when(
           period3 == "Pre-reform" ~ days.pre,
           period3 == "Reform" ~ days.reform,
           period3 == "Post-modify" ~ days.modify)
  )

p <- ggplot(period3_df, 
            aes(x = period3, y = ratepermo)
            )  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
               ),
           alpha=0.5, color="grey",
           stat="identity"
           ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate") 
  
ggplotly(p, tooltip = "text")

2 Policy periods

#### Avg monthly pursuit rate plot template: 2 Policy periods

period2_df <- inci_df %>% 
  mutate(period2 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform ~ "Post-reform"), 
    c("Pre-reform", "Post-reform"))
  ) %>%
  group_by(period2) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
           period2 == "Pre-reform" ~ count/days.pre *30,
           period2 == "Post-reform" ~ count/days.reform *30),
         days = case_when(
           period2 == "Pre-reform" ~ days.pre,
           period2 == "Post-reform" ~ days.reformtot)
  )

p <- ggplot(period2_df, 
            aes(x = period2, y = ratepermo)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
  ),
  alpha=0.5, color="grey",
  stat="identity"
  ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") 

ggplotly(p, tooltip = "text")

Zero pursuit month comparison

3 policy periods

#### Zero pursuit months plot template: 3 policy periods

zmonths3_df <- monthly_df %>%
  group_by(period3) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths3_df, 
            aes(x = period3, y = zmpct)
)  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
               ),
           alpha=0.5, color="grey",
           stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

2 policy periods

#### Zero pursuit months plot template: 2 policy periods

zmonths2_df <- monthly_df %>%
  group_by(period2) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths2_df, 
            aes(x = period2, y = zmpct)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
  ),
  alpha=0.5, color="grey",
  stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits:", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

Notes

### Notes/Info on data
print(notes)
## $format
## [1] "RMS extract PDF"
## 
## $uoa
## [1] "incident"
## 
## $range
## [1] "1/1/2019-12/31/2023"
## 
## $sample
## [1] "AWC"
## 
## $limitations
## [1] "When date is missing from Narrative field (52 cases) we use Received date. Received date != narrative incident date in 19 cases (~20% of non-missing cases) but none of the discrepant cases have different months, just different days."

Battle Ground PD (Accredited, AWC)

load(here::here("AWC-Signatories", "Battle Ground - closed", "battleGround.rda"))
jurisdiction <- "Battle Ground PD"
inci_df <- battleGround.inci %>%
  mutate(incidate = date) # note starts in 2015
notes <- battleGround.notes

Monthly pursuit time series

### Monthly pursuit count time series plot template

monthly_df <- inci_df %>% group_by(yr, mo) %>%
  count() %>%
  left_join(index, ., by = c("yr", "mo")) %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         numdate = as.numeric(index.date),
         period3 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform & index.date < date.modify ~ "Reform",
             index.date >= date.modify ~ "Post-modify"), 
           c("Pre-reform", "Reform", "Post-modify")),
         period2 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform ~ "Post-reform"), 
           c("Pre-reform", "Post-reform"))
  )

p <- ggplot(monthly_df, 
            aes(x = index.date, y = count)
       )  +
  
  geom_bar(aes(fill = factor(yr), text = paste0(mon.yr, ": ", count)),
           alpha=0.5, color="grey",
           stat="identity"
  ) +
  scale_fill_brewer(palette="Spectral") +
             
  geom_smooth(span = 0.5, linetype="dot", linewidth=.5) +
  
  # year boundaries
  geom_vline(xintercept = yrs, col="white", alpha=.5) +
  
  # dates
  geom_vline(xintercept = date.reform, col="darkgrey", alpha=.5) +
  geom_vline(xintercept = date.modify, col="darkgrey", alpha=.5) +
  
  annotate("text", x=(as.numeric(date.reform) - as.numeric(date.reform-date.start)/2),
           y=max(monthly_df$count)+0.5, 
           label="Pre-reform",
           size=3) +
  annotate("text", x=(as.numeric(date.reform) + as.numeric(date.modify-date.reform)/2),
           y=max(monthly_df$count)+0.5, 
           label="Reform",
           size=3) +
  annotate("text", x=(as.numeric(date.modify)+150), 
           y=max(monthly_df$count)+0.5, 
           label="Post-Modified",
           size=3) +
  
  
  geom_hline(yintercept = 0, col="grey") +
  
  labs(title = paste("Monthly pursuits:", jurisdiction, min(index$yr), "-", max(index$yr)),
       x = "Month.Year",
       y = "Number of pursuits",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") +
  
  scale_x_continuous(
    breaks = monthly_df$index.date[seq(1, nrow(monthly_df), 6)],
    label = monthly_df$mon.yr[seq(1, nrow(monthly_df), 6)]
  )  +
  
#  scale_y_continuous(limits = c(-2, max(monthly_df$count)+0.5), breaks = 0:max(monthly_df$count)) +
  scale_y_continuous(limits = c(-2, max(monthly_df$count, 10)+0.5), breaks = 0:max(monthly_df$count, 10)) +
  
  theme(axis.text.x = element_text(size=7, angle = 45, vjust = 0.5)) +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank())

ggplotly(p, tooltip = "text")

Pre-post plots

3 Policy periods

#### Avg monthly pursuit rate plot template: 3 Policy periods

period3_df <- inci_df %>% 
  mutate(period3 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform & incidate < date.modify ~ "Reform",
      incidate >= date.modify ~ "Post-modify"), 
    c("Pre-reform", "Reform", "Post-modify"))
  ) %>%
  group_by(period3) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
             period3 == "Pre-reform" ~ count/days.pre *30,
             period3 == "Reform" ~ count/days.reform *30,
             period3 == "Post-modify" ~ count/days.modify *30),
         days = case_when(
           period3 == "Pre-reform" ~ days.pre,
           period3 == "Reform" ~ days.reform,
           period3 == "Post-modify" ~ days.modify)
  )

p <- ggplot(period3_df, 
            aes(x = period3, y = ratepermo)
            )  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
               ),
           alpha=0.5, color="grey",
           stat="identity"
           ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate") 
  
ggplotly(p, tooltip = "text")

2 Policy periods

#### Avg monthly pursuit rate plot template: 2 Policy periods

period2_df <- inci_df %>% 
  mutate(period2 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform ~ "Post-reform"), 
    c("Pre-reform", "Post-reform"))
  ) %>%
  group_by(period2) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
           period2 == "Pre-reform" ~ count/days.pre *30,
           period2 == "Post-reform" ~ count/days.reform *30),
         days = case_when(
           period2 == "Pre-reform" ~ days.pre,
           period2 == "Post-reform" ~ days.reformtot)
  )

p <- ggplot(period2_df, 
            aes(x = period2, y = ratepermo)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
  ),
  alpha=0.5, color="grey",
  stat="identity"
  ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") 

ggplotly(p, tooltip = "text")

Zero pursuit month comparison

3 policy periods

#### Zero pursuit months plot template: 3 policy periods

zmonths3_df <- monthly_df %>%
  group_by(period3) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths3_df, 
            aes(x = period3, y = zmpct)
)  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
               ),
           alpha=0.5, color="grey",
           stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

2 policy periods

#### Zero pursuit months plot template: 2 policy periods

zmonths2_df <- monthly_df %>%
  group_by(period2) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths2_df, 
            aes(x = period2, y = zmpct)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
  ),
  alpha=0.5, color="grey",
  stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits:", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

Notes

### Notes/Info on data
print(notes)
## $format
## [1] "RMS extract PDF"
## 
## $uoa
## [1] "incident"
## 
## $range
## [1] "1/1/2015-12/31/2023"
## 
## $sample
## [1] "Accredited" "AWC"       
## 
## $limitations
## [1] "Two data files sent, not consistent.  Using the file that matches the annual pursuit review report numbers."

Bellevue PD (AWC)

load(here::here("AWC-Signatories", "Bellevue - closed", "bellevue.rda"))
jurisdiction <- "Bellevue PD"
inci_df <- bellevue.inci %>%
  mutate(incidate = date)
notes <- bellevue.notes

Monthly pursuit time series

### Monthly pursuit count time series plot template

monthly_df <- inci_df %>% group_by(yr, mo) %>%
  count() %>%
  left_join(index, ., by = c("yr", "mo")) %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         numdate = as.numeric(index.date),
         period3 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform & index.date < date.modify ~ "Reform",
             index.date >= date.modify ~ "Post-modify"), 
           c("Pre-reform", "Reform", "Post-modify")),
         period2 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform ~ "Post-reform"), 
           c("Pre-reform", "Post-reform"))
  )

p <- ggplot(monthly_df, 
            aes(x = index.date, y = count)
       )  +
  
  geom_bar(aes(fill = factor(yr), text = paste0(mon.yr, ": ", count)),
           alpha=0.5, color="grey",
           stat="identity"
  ) +
  scale_fill_brewer(palette="Spectral") +
             
  geom_smooth(span = 0.5, linetype="dot", linewidth=.5) +
  
  # year boundaries
  geom_vline(xintercept = yrs, col="white", alpha=.5) +
  
  # dates
  geom_vline(xintercept = date.reform, col="darkgrey", alpha=.5) +
  geom_vline(xintercept = date.modify, col="darkgrey", alpha=.5) +
  
  annotate("text", x=(as.numeric(date.reform) - as.numeric(date.reform-date.start)/2),
           y=max(monthly_df$count)+0.5, 
           label="Pre-reform",
           size=3) +
  annotate("text", x=(as.numeric(date.reform) + as.numeric(date.modify-date.reform)/2),
           y=max(monthly_df$count)+0.5, 
           label="Reform",
           size=3) +
  annotate("text", x=(as.numeric(date.modify)+150), 
           y=max(monthly_df$count)+0.5, 
           label="Post-Modified",
           size=3) +
  
  
  geom_hline(yintercept = 0, col="grey") +
  
  labs(title = paste("Monthly pursuits:", jurisdiction, min(index$yr), "-", max(index$yr)),
       x = "Month.Year",
       y = "Number of pursuits",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") +
  
  scale_x_continuous(
    breaks = monthly_df$index.date[seq(1, nrow(monthly_df), 6)],
    label = monthly_df$mon.yr[seq(1, nrow(monthly_df), 6)]
  )  +
  
#  scale_y_continuous(limits = c(-2, max(monthly_df$count)+0.5), breaks = 0:max(monthly_df$count)) +
  scale_y_continuous(limits = c(-2, max(monthly_df$count, 10)+0.5), breaks = 0:max(monthly_df$count, 10)) +
  
  theme(axis.text.x = element_text(size=7, angle = 45, vjust = 0.5)) +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank())

ggplotly(p, tooltip = "text")

Pre-post plots

3 Policy periods

#### Avg monthly pursuit rate plot template: 3 Policy periods

period3_df <- inci_df %>% 
  mutate(period3 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform & incidate < date.modify ~ "Reform",
      incidate >= date.modify ~ "Post-modify"), 
    c("Pre-reform", "Reform", "Post-modify"))
  ) %>%
  group_by(period3) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
             period3 == "Pre-reform" ~ count/days.pre *30,
             period3 == "Reform" ~ count/days.reform *30,
             period3 == "Post-modify" ~ count/days.modify *30),
         days = case_when(
           period3 == "Pre-reform" ~ days.pre,
           period3 == "Reform" ~ days.reform,
           period3 == "Post-modify" ~ days.modify)
  )

p <- ggplot(period3_df, 
            aes(x = period3, y = ratepermo)
            )  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
               ),
           alpha=0.5, color="grey",
           stat="identity"
           ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate") 
  
ggplotly(p, tooltip = "text")

2 Policy periods

#### Avg monthly pursuit rate plot template: 2 Policy periods

period2_df <- inci_df %>% 
  mutate(period2 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform ~ "Post-reform"), 
    c("Pre-reform", "Post-reform"))
  ) %>%
  group_by(period2) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
           period2 == "Pre-reform" ~ count/days.pre *30,
           period2 == "Post-reform" ~ count/days.reform *30),
         days = case_when(
           period2 == "Pre-reform" ~ days.pre,
           period2 == "Post-reform" ~ days.reformtot)
  )

p <- ggplot(period2_df, 
            aes(x = period2, y = ratepermo)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
  ),
  alpha=0.5, color="grey",
  stat="identity"
  ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") 

ggplotly(p, tooltip = "text")

Zero pursuit month comparison

3 policy periods

#### Zero pursuit months plot template: 3 policy periods

zmonths3_df <- monthly_df %>%
  group_by(period3) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths3_df, 
            aes(x = period3, y = zmpct)
)  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
               ),
           alpha=0.5, color="grey",
           stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

2 policy periods

#### Zero pursuit months plot template: 2 policy periods

zmonths2_df <- monthly_df %>%
  group_by(period2) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths2_df, 
            aes(x = period2, y = zmpct)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
  ),
  alpha=0.5, color="grey",
  stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits:", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

Notes

### Notes/Info on data
print(notes)
## $format
## [1] "RMS extract"
## 
## $uoa
## [1] "incident"
## 
## $range
## [1] "1/1/2019-12/31/2023"
## 
## $sample
## [1] "AWC"
## 
## $limitations
## [1] "Bellevue PD is accredited by CALEA (since 2005) but not WASPC"

Des Moines PD (AWC)

load(here::here("AWC-Signatories", "Des Moines - closed", "desmoines.RDA"))
jurisdiction <- "DesMoines PD"
inci_df <- desmoines.inci %>%
  mutate(incidate = rdate)
notes <- desmoines.notes

Monthly pursuit time series

### Monthly pursuit count time series plot template

monthly_df <- inci_df %>% group_by(yr, mo) %>%
  count() %>%
  left_join(index, ., by = c("yr", "mo")) %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         numdate = as.numeric(index.date),
         period3 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform & index.date < date.modify ~ "Reform",
             index.date >= date.modify ~ "Post-modify"), 
           c("Pre-reform", "Reform", "Post-modify")),
         period2 = factor(
           case_when(
             index.date < date.reform ~ "Pre-reform",
             index.date >= date.reform ~ "Post-reform"), 
           c("Pre-reform", "Post-reform"))
  )

p <- ggplot(monthly_df, 
            aes(x = index.date, y = count)
       )  +
  
  geom_bar(aes(fill = factor(yr), text = paste0(mon.yr, ": ", count)),
           alpha=0.5, color="grey",
           stat="identity"
  ) +
  scale_fill_brewer(palette="Spectral") +
             
  geom_smooth(span = 0.5, linetype="dot", linewidth=.5) +
  
  # year boundaries
  geom_vline(xintercept = yrs, col="white", alpha=.5) +
  
  # dates
  geom_vline(xintercept = date.reform, col="darkgrey", alpha=.5) +
  geom_vline(xintercept = date.modify, col="darkgrey", alpha=.5) +
  
  annotate("text", x=(as.numeric(date.reform) - as.numeric(date.reform-date.start)/2),
           y=max(monthly_df$count)+0.5, 
           label="Pre-reform",
           size=3) +
  annotate("text", x=(as.numeric(date.reform) + as.numeric(date.modify-date.reform)/2),
           y=max(monthly_df$count)+0.5, 
           label="Reform",
           size=3) +
  annotate("text", x=(as.numeric(date.modify)+150), 
           y=max(monthly_df$count)+0.5, 
           label="Post-Modified",
           size=3) +
  
  
  geom_hline(yintercept = 0, col="grey") +
  
  labs(title = paste("Monthly pursuits:", jurisdiction, min(index$yr), "-", max(index$yr)),
       x = "Month.Year",
       y = "Number of pursuits",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") +
  
  scale_x_continuous(
    breaks = monthly_df$index.date[seq(1, nrow(monthly_df), 6)],
    label = monthly_df$mon.yr[seq(1, nrow(monthly_df), 6)]
  )  +
  
#  scale_y_continuous(limits = c(-2, max(monthly_df$count)+0.5), breaks = 0:max(monthly_df$count)) +
  scale_y_continuous(limits = c(-2, max(monthly_df$count, 10)+0.5), breaks = 0:max(monthly_df$count, 10)) +
  
  theme(axis.text.x = element_text(size=7, angle = 45, vjust = 0.5)) +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank())

ggplotly(p, tooltip = "text")

Pre-post plots

3 Policy periods

#### Avg monthly pursuit rate plot template: 3 Policy periods

period3_df <- inci_df %>% 
  mutate(period3 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform & incidate < date.modify ~ "Reform",
      incidate >= date.modify ~ "Post-modify"), 
    c("Pre-reform", "Reform", "Post-modify"))
  ) %>%
  group_by(period3) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
             period3 == "Pre-reform" ~ count/days.pre *30,
             period3 == "Reform" ~ count/days.reform *30,
             period3 == "Post-modify" ~ count/days.modify *30),
         days = case_when(
           period3 == "Pre-reform" ~ days.pre,
           period3 == "Reform" ~ days.reform,
           period3 == "Post-modify" ~ days.modify)
  )

p <- ggplot(period3_df, 
            aes(x = period3, y = ratepermo)
            )  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
               ),
           alpha=0.5, color="grey",
           stat="identity"
           ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate") 
  
ggplotly(p, tooltip = "text")

2 Policy periods

#### Avg monthly pursuit rate plot template: 2 Policy periods

period2_df <- inci_df %>% 
  mutate(period2 = factor(
    case_when(
      incidate < date.reform ~ "Pre-reform",
      incidate >= date.reform ~ "Post-reform"), 
    c("Pre-reform", "Post-reform"))
  ) %>%
  group_by(period2) %>%
  count() %>%
  mutate(count = as.numeric(tidyr::replace_na(n, 0)),
         ratepermo = case_when(
           period2 == "Pre-reform" ~ count/days.pre *30,
           period2 == "Post-reform" ~ count/days.reform *30),
         days = case_when(
           period2 == "Pre-reform" ~ days.pre,
           period2 == "Post-reform" ~ days.reformtot)
  )

p <- ggplot(period2_df, 
            aes(x = period2, y = ratepermo)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Pursuits: ", count, "<br>",
                            "Days in period: ", days, "<br>",
                            "Monthly Rate: ", round(ratepermo, 2))
  ),
  alpha=0.5, color="grey",
  stat="identity"
  ) +
  scale_fill_brewer(palette="Blues") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Average monthly pursuit rate:", jurisdiction),
       x = "Policy Period",
       y = "Monthly pursuit rate",
       #caption = paste(jurisdiction, min(index$yr), "-", max(index$yr)),
       fill = "Year") 

ggplotly(p, tooltip = "text")

Zero pursuit month comparison

3 policy periods

#### Zero pursuit months plot template: 3 policy periods

zmonths3_df <- monthly_df %>%
  group_by(period3) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths3_df, 
            aes(x = period3, y = zmpct)
)  +
  
  geom_bar(aes(fill = period3, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
               ),
           alpha=0.5, color="grey",
           stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

2 policy periods

#### Zero pursuit months plot template: 2 policy periods

zmonths2_df <- monthly_df %>%
  group_by(period2) %>%
  summarize(nummonths = n(),
            zeromonths = sum(count==0)) %>%
  mutate(zmpct = round(100*zeromonths/nummonths, 2))

p <- ggplot(zmonths2_df, 
            aes(x = period2, y = zmpct)
)  +
  
  geom_bar(aes(fill = period2, 
               text = paste("Zero pursuit months: ", zeromonths, "<br>",
                            "Months in period: ", nummonths, "<br>",
                            "Zero pursuit month %: ", round(zmpct, 1))
  ),
  alpha=0.5, color="grey",
  stat="identity") +
  
  scale_fill_brewer(palette="Oranges") +
  
  theme(legend.position="none") +
  
  labs(title = paste("Percent of months with no pursuits:", jurisdiction),
       x = "Policy Period",
       y = "Percent of months") 

ggplotly(p, tooltip = "text")

Notes

### Notes/Info on data
print(notes)
## $format
## [1] "xls"
## 
## $uoa
## [1] "incident"
## 
## $range
## [1] "1/1/2019-12/31/2023"
## 
## $sample
## [1] "AWC"
## 
## $limitations
## [1] "none known"

Pursuit legislation

Statewide pursuit policy was first adopted in 2021 and modified twice. The current RCW can be found online here

2021 legislation

The full text of HB 1054 as passed by the WA State legislature in 2021 can be found online here.

The section addressing vehicle pursuits reads:

knitr::include_graphics(here::here("Documents", "Legislation", "HB1054-SECTION.PNG"))

2023 legislation

The full text of SB 5352 as passed by the WA State legislature in 2023 can be found online here.

The key section changed by SB 5352 reads:

knitr::include_graphics(here::here("Documents", "Legislation", "SB5352screenshot.png"))

2024 legislation

The full text of SB 5352 as passed by the WA State legislature in 2023 can be found online here

The key sections changed by Initiative 2113 read:

knitr::include_graphics(here::here("Documents", "Legislation", "I2113screenshot.png"))