Code: NZ Police pursuits keep killing people

This document describes how data was analysed and how figures were produced for the article NZ Police pursuits keep killing people.

This article relied on two sources of data for the graphs it produced.

I used my Charter data analysis library to load and process the data and to produce all the graphs used in the article.

Police regularly release road policing driver offence data. This article used the 2009-2017 data released on the NZ Police website.

When Police release new data on their website, they overwrite the existing data and direct older pages to the most recent page. At the time this page was written, nearly two years after the article was published, the road policing driver offence data published on the NZ Police website covered January 2009 - December 2019.

However, the article was based on data extracted in 2018, which only covered up until 2017. A copy of this older data is available, but I will stress that more up-to-date information is available on the NZ Police website.

Before being analysed, I extracted the "Fleeding Drivers" sheet from the road policing driver offence data spreadsheet, and converted it to CSV format using Google Drive. The "Fleeing driver incidents" table was then extracted from this CSV and transposed so that the regions were reflected by columns and each row was one month.

Some hand editing was also necessary to delete rows that had been used for formatting and the "total" rows for each calendar year, and to add missing month labels for October 2016 onwards.

Road policing driver offence data, fleeing drivers - January 2009 to December 2017 (CSV)

This data was loaded into Charter using this code:

const fileConfig = { headerRows: 1, cols: Analyser.getColNumbers({ MONTH: 'A', AUCKLAND_CITY: 'B', BAY_OF_PLENTY: 'C', CANTERBURY: 'D', CENTRAL: 'E', COUNTIES_MANUKAU: 'F', EASTERN: 'G', NORTHLAND: 'H', SOUTHERN: 'I', TASMAN: 'J', WAIKATO: 'K', WAITEMATA: 'L', WELLINGTON: 'M', ALL: 'N' }) }; Analyser.loadFile('../data/2009-01-01 - 2017-12-31 Road policing driver offence data - Fleeing Drivers.csv', fileConfig, analyseData);

The "Police Pursuits" chart was created using the road policing driver offence data. This code was used to create a line graph of police pursuits per month:

let labels = rows.getCol(cols.MONTH); // Replace hyphen with non-breaking hyphen labels = labels.map(month => month.replace('-', '‑')); const pursuitsChart = { title: 'Police Pursuits', showLegend: true, showTooltips: true, labels: labels, dataSeries: [ { name: 'Pursuits per month', color: '#66c', dataPoints: rows.getCol(cols.ALL) } ] }; const pursuitsAxisY = { min: 0, max: 400, values: 4 }; const pursuitsAxisX = { valuesEvery: 12 }; let $pursuitsChart = Charter.createLineGraph(pursuitsChart, pursuitsAxisY, pursuitsAxisX); chart($pursuitsChart);

In February 2018, I asked Police to release certain statistics on Police pursuits under the Official Information Act:

Please release the following information:

1. The current New Zealand Police pursuit policy.
1a. All past iterations of the New Zealand Police pursuit policy that were in use from 1 January 2012, and the dates on which they were introduced.

Please release the following information, broken down by month, from January 2012 until the most recent month for which data is available:

2. The number of police pursuits.
3. The number of police pursuits that were abandoned.
4. The number of police pursuits that resulted in at least one injury.
4a. The number of injuries that were the result of a police pursuit, broken down by offender and police officer.
5. The number of police pursuits that resulted in at least one death.
5a. The number of deaths that were the result of a police pursuit, broken down by offender and police officer.

Police pursuit policy and statistics | Mark Hanna

After receiving Police's response, I sent a follow-up request after observing a discrepancy between the information I had been provided and media reports, and realising I had not asked about injuries and deaths of bystanders:

I've been looking through the information released and I have some follow-up questions I hope you'll be able to help me with.

1. The spreadsheet lists no offender deaths during July 2017, but there were media reports of a motorcyclist who died in a police pursuit in July 2017 in Māngere: http://www.nzherald.co.nz/nz/news/article.cfm?c_id=1&objectid=11894208

Is there any particular reason why this death was not included in the spreadsheet, and are there likely to be other similar deaths that have been excluded?

2. Since sending the request last month, I've realised that I worded part of it poorly. In asking that injuries and deaths be broken down by offenders and police, I neglected to ask about injuries and deaths of bystanders.

In the IPCA's report on their 2009 review of police pursuits they reported that, from 19 December 2003 to 19 December 2008, three innocent members of the public died in police pursuits, 18 were seriously injured, and 29 suffered minor injuries. In that period, that amounted to 14% of deaths, 25% of all serious injuries, and 29% of minor injuries. So I am now concerned that the way I worded my request may potentially have excluded a significant number of injuries and deaths.

Though I had intended that parts 4a and 5a would each cover all injuries and all deaths, given the breakdown I had requested I can understand why it was interpreted to only include injuries and deaths of offenders and police.

Could you please provide the equivalent statistics for injuries and deaths to bystanders in pursuits, and any other relevant categories of person that I may have missed, for the same period?

Police pursuit policy and statistics follow-up | Mark Hanna

Police assured me that the single discrepancy I had found was the only one:

Data used to produce this report is sourced from the Fleeding Driver Notification Database. If a notification is not fully completed, then information about that particular pursuit will not appear in any report. As previously stated the data provided is drawn from a dynamic operational database that is subject to change as new information is recorded or recoded. In this instance one notification was not completed, and another was completed several months after the crash. As these had not been completed in a timely manner, they did not show up in any reports generated from this database. A detailed examination of the fleeing driver notifications has been undertaken, cross-matching them with fatal crashes in the NZTA Crash Analysis System (CAS). Police are now confident that the data it holds on fatal fleeing driver incidents is accurate and measures are to be put in place to ensure that any future fatal fleeing driver event notifications will be completed in a timely manner.

NZ Police

Police also sent me revised data including the information on injuries and deaths to bystanders I had asked for. They included this note alongside the information:

Please note that the 'Offender' category includes any persons in the offending vehicle and the 'Third Party' category includes occupants of any other vehicle involved, pedestrians, cyclists or any other road users.

NZ Police

The revised data they provided can be found here:

Hanna Mark 16 7758 14 Pursuit data.xlsx

I converted this spreadsheet to CSV format using Google Drive, and the explanatory note and two empty formatting rows were removed for ease of processing the file:

Hanna Mark 16 7758 14 Pursuit data.xlsx - Sheet1.csv

This data was loaded into Charter using this code:

const cols = Analyser.getColNumbers({ MONTH: 'A', PURSUITS_TOTAL: 'B', PURSUITS_ABANDONED: 'C', PURSUITS_INJURY: 'D', PURSUITS_FATAL: 'H', OFFENDERS_INJURY: 'E', OFFENDERS_DEATH: 'I', POLICE_INJURY: 'F', BYSTANDERS_INJURY: 'G', BYSTANDERS_DEATH: 'J' }); const defaultCols = { [cols.PURSUITS_TOTAL]: 0, [cols.PURSUITS_ABANDONED]: 0, [cols.PURSUITS_INJURY]: 0, [cols.PURSUITS_FATAL]: 0, [cols.OFFENDERS_INJURY]: 0, [cols.OFFENDERS_DEATH]: 0, [cols.POLICE_INJURY]: 0, [cols.BYSTANDERS_INJURY]: 0, [cols.BYSTANDERS_DEATH]: 0 }; const fileConfig = { headerRows: 1, cols, defaultCols }; Analyser.loadFile('../data/Hanna Mark 16 7758 14 Pursuit data.xlsx - Sheet1.csv', fileConfig, analyseData);

The "Abandoned Police Pursuits" chart was created using the pursuit statistics released by NZ Police under the Official Information Act.

This code was used to calculate the rate at which pursuits were abandoned each month, and to produce a line graph showing this rate:

let getAbandonedPursuitsPercent = function (row) { let abandoned = row[cols.PURSUITS_ABANDONED]; let pursuits = row[cols.PURSUITS_TOTAL]; let abandonedPercent = abandoned/pursuits; return abandonedPercent; }; cols.PURSUITS_ABANDONED_PERCENT = rows.addDerivedCol(getAbandonedPursuitsPercent); let labels = rows.getCol(cols.MONTH); // Replace hyphen with non-breaking hyphen labels = labels.map(month => month.replace('-', '‑')); const abandonedPursuitsChart = { title: 'Abandoned Police Pursuits', showLegend: true, showTooltips: true, labels: labels, dataSeries: [ { name: 'Abandoned pursuits', color: '#66c', dataPoints: rows.getCol(cols.PURSUITS_ABANDONED_PERCENT) } ] }; const abandonedPursuitsAxisY = { min: 0, max: 1, values: 4, toFixed: 0, percentage: true }; const abandonedPursuitsAxisX = { valuesEvery: 12 }; let $abandonedPursuitsChart = Charter.createLineGraph(abandonedPursuitsChart, abandonedPursuitsAxisY, abandonedPursuitsAxisX); chart($abandonedPursuitsChart);

The graph "Injury Rate in Police Pursuits" was created by calculating the number of people injured per month, and dividing it by the number of pursuits. Because the number of injuries per month is quite sporadic, the graph was produced using combined numbers for sets of three months.

This code was used to create it:

let pursuitQuarters = Stats.chunk(rows.getCol(cols.PURSUITS_TOTAL), 3); let getNumPeopleInjured = function (row) { let numPeopleInjured = row[cols.OFFENDERS_INJURY] + row[cols.POLICE_INJURY] + row[cols.BYSTANDERS_INJURY]; return numPeopleInjured; }; cols.TOTAL_INJURED = rows.addDerivedCol(getNumPeopleInjured); let pursuitInjuryQuarters = Stats.chunk(rows.getCol(cols.TOTAL_INJURED), 3); let pursuitInjuryRateQuarters = pursuitInjuryQuarters.map((el, i) => el / pursuitQuarters[i]); const quarterLabels = ['Q1 2012', 'Q2 2012', 'Q3 2012', 'Q4 2012', 'Q1 2013', 'Q2 2013', 'Q3 2013', 'Q4 2013', 'Q1 2014', 'Q2 2014', 'Q3 2014', 'Q4 2014', 'Q1 2015', 'Q2 2015', 'Q3 2015', 'Q4 2015', 'Q1 2016', 'Q2 2016', 'Q3 2016', 'Q4 2016', 'Q1 2017', 'Q2 2017', 'Q3 2017', 'Q4 2017', 'Q1 2018']; const injuryRateChart = { title: 'Injury Rate in Police Pursuits', showLegend: true, showTooltips: true, labels: quarterLabels, dataSeries: [ { name: 'Injury rate', color: '#933', dataPoints: pursuitInjuryRateQuarters } ] }; const injuryRateAxisY = { min: 0, values: 5, toFixed: 0, percentage: true }; const injuryRateAxisX = { valuesEvery: 2 }; let $injuryRateChart = Charter.createLineGraph(injuryRateChart, injuryRateAxisY, injuryRateAxisX); chart($injuryRateChart);

The graph "Deaths in Police Pursuits" was created using the combined figures for each calendar year.

This code was used to create it:

let getNumDeaths = function (row) { // No police deaths column to count let numDeaths = row[cols.OFFENDERS_DEATH] + row[cols.BYSTANDERS_DEATH]; return numDeaths; }; cols.TOTAL_DEATH = rows.addDerivedCol(getNumDeaths); let pursuitDeathYears = Stats.chunk(rows.getCol(cols.TOTAL_DEATH), 12); // Remove last item because the year is incomplete pursuitDeathYears.pop(); const yearLabels = ['2012', '2013', '2014', '2015', '2016', '2017']; const pursuitDeathChart = { title: 'Deaths in Police Pursuits', showLegend: true, showTooltips: false, labels: yearLabels, dataSeries: [ { name: 'Deaths', color: '#933', dataPoints: pursuitDeathYears } ] }; const pursuitDeathAxisY = { min: 0, max: 15, values: 5, toFixed: 0 }; const pursuitDeathAxisX = { valuesEvery: 2 }; let $pursuitDeathChart = Charter.createBarChart(pursuitDeathChart, pursuitDeathAxisY, pursuitDeathAxisX); chart($pursuitDeathChart);