Table of Contents
- Officers in Schools: The number of officers in schools rose sharply in the 90s and then held steady until 2014.
- Weapons Officers Carry Between 2006 and 2010, schools that employed officers saw an 8-point rise in tasers and an 8-point drop in firearms.
- COPS Funding Most federal grants to hire SROs came in the 90s and early 2000s.
This is a Jupyter notebook. It uses the R programming language.
First, some boilerplate R:
# install.packages('ggplot2')
## install.packages('prettyR') # for lemas13
#
# Haven 0.2.0 can't read a compressed SAS file. Install GitHub version by
# running this:
#
# library(devtools); devtools::install_github('hadley/haven')
library(haven) # to read SPSS and SAS files
library(ggplot2) # to build charts
library(foreign) # for xport file
# Keep file size small-ish, so GitHub renders it
options(
jupyter.plot_mimetypes='image/png',
repr.plot.width = 6,
repr.plot.height = 4
)
Input
SSOCS: School Survey on Crime and Safety
The National Center for Education Statistics (NCES) sends surveys to school pricipals from time to time. Download the SPSS data files from their data_products page. Their 2010 download page is separate.
Unzip all the .sav
files into data/
. Then we'll load them:
ssocs00 <- read_sav('data/SSOCS/SSOCS1.sav')
ssocs04 <- read_sav('data/SSOCS/ssocs_puf.sav')
ssocs06 <- read_sav('data/SSOCS/pu_ssocs06_spss.sav')
ssocs08 <- read_sav('data/SSOCS/pu_ssocs08_spss.sav')
ssocs10 <- read_sav('data/SSOCS/pu_ssocs10_spss.sav')
FRSS_SSD: Fast Response Survey System, School Safety and Discipline
To make up for a gap in the SSOCS responses, we consider one other NCES survey from 2014. It has a couple of questions that are identical to the SSOCS ones, and the methodology is very similar, so we can make comparisons.
The full disclaimer, from http://nces.ed.gov/programs/digest/d15/tables/dt15_233.70.asp:
Data for 2013-14 were collected using the Fast Response Survey System, while data for earlier years were collected using the School Survey on Crime and Safety (SSOCS). The 2013-14 survey was designed to allow comparisons with SSOCS data. However, respondents to the 2013-14 survey could choose either to complete the survey on paper (and mail it back) or to complete the survey online, whereas respondents to SSOCS did not have the option of completing the survey online. The 2013-14 survey also relied on a smaller sample. The smaller sample size and change in survey administration may have impacted 2013-14 results.
Then there's an old survey not in data form. It has a percentage of schools with school resource officers.
frss_ssd14 <- read_sas('data/FRSS/frss106puf.sas7bdat')
frss_vdpups97 <- list(
year=1997,
n=77752,
percent_ft_officer=6,
percent_pt_officer=4,
percent_officer=10
)
# Now add lots of variables to the data frame, to make summary "ssocs" data frame
# YEAR
ssocs00$year <- 2000L
ssocs04$year <- 2004L
ssocs06$year <- 2006L
ssocs08$year <- 2008L
ssocs10$year <- 2010L
frss_ssd14$year <- 2014L
# WEIGHT
# Some schools "count" for more than others. Here's the weight of each school:
ssocs00$weight <- ssocs00$FWT
ssocs04$weight <- ssocs04$FINALWGT
ssocs06$weight <- ssocs06$FINALWGT
ssocs08$weight <- ssocs08$FINALWGT
ssocs10$weight <- ssocs10$FINALWGT
frss_ssd14$weight <- frss_ssd14$AWT
# HAS_OFFICER
# During the 1999-2000 school year, at what times did your school regularly
# use paid law enforcement or security services at school? (Circle one response on each line.)
# ... At any time during school hours
# 1=yes
# 2=no
ssocs00$has_officer <- !is.na(ssocs00$Q8A) & ssocs00$Q8A == 1
# During the 2003-2004 school year, did you have any sworn law enforcement officers,
# security guards, or security personnel present at your school on a regular basis?
# 1=yes
ssocs04$has_officer <- ssocs04$Q7 == 1
# 2008: changed to clarify "at least once a week"
ssocs06$has_officer <- ssocs06$C0220 == 1
ssocs08$has_officer <- ssocs08$C0220 == 1
# Beware: In 2010 the questionnaire changed. 2004-2008 had columns for part-time vs
# full-time; in 2010 there's a single column.
ssocs10$has_officer <- ssocs10$C0220 == 1
frss_ssd14$has_officer <- frss_ssd14$Q4 == 1
# N_FULL_TIME_OFFICERS
ssocs00$n_full_time_officers <- NA
# In 2004-2006, the number of officers is "topcoded": if an agency has more than 10
# officers, the survey says it had 11.
ssocs04$n_full_time_officers <- ifelse(ssocs04$Q9A1 > 0, ssocs04$Q9A1, 0) +
ifelse(ssocs04$Q9B1 > 0, ssocs04$Q9B1, 0) +
ifelse(ssocs04$Q9C1 > 0, ssocs04$Q9C1, 0)
ssocs06$n_full_time_officers <- ifelse(strtoi(ssocs06$C0232_R, 10) > 0, strtoi(ssocs06$C0232_R, 10), 0) +
ifelse(strtoi(ssocs06$C0236_R, 10) > 0, strtoi(ssocs06$C0236_R, 10), 0) +
ifelse(strtoi(ssocs06$C0240_R, 10) > 0, strtoi(ssocs06$C0240_R, 10), 0)
ssocs08$n_full_time_officers <- ifelse(ssocs08$SEC_FT > 0, ssocs08$SEC_FT, 0)
ssocs10$n_full_time_officers <- ifelse(ssocs10$SEC_FT10 > 0, ssocs10$SEC_FT10, 0)
frss_ssd14$n_full_time_officers <- ifelse(frss_ssd14$T_Q5FT > 0, frss_ssd14$T_Q5FT, 0)
# N_PART_TIME_OFFICERS
ssocs00$n_part_time_officers <- NA
ssocs04$n_part_time_officers <- ifelse(ssocs04$Q9A2 > 0, ssocs04$Q9A2, 0) +
ifelse(ssocs04$Q9B2 > 0, ssocs04$Q9B2, 0) +
ifelse(ssocs04$Q9C2 > 0, ssocs04$Q9C2, 0)
ssocs06$n_part_time_officers <- ifelse(strtoi(ssocs06$C0234_R, 10) > 0, strtoi(ssocs06$C0234_R, 10), 0) +
ifelse(strtoi(ssocs06$C0238_R, 10) > 0, strtoi(ssocs06$C0238_R, 10), 0) +
ifelse(strtoi(ssocs06$C0242_R, 10) > 0, strtoi(ssocs06$C0242_R, 10), 0)
ssocs08$n_part_time_officers <- ifelse(ssocs08$SEC_PT > 0, ssocs08$SEC_PT, 0)
ssocs10$n_part_time_officers <- ifelse(ssocs10$SEC_PT10 > 0, ssocs10$SEC_PT10, 0)
frss_ssd14$n_part_time_officers <- ifelse(frss_ssd14$T_Q5PT > 0, frss_ssd14$T_Q5PT, 0)
# N_WITH_TASER, N_WITH_SPRAY, N_WITH_FIREARM
#
# Different officers carry different weapons. This is a survey of _schools_,
# not officers, so all we can know is whether the _school_ has officers with
# certain weapons.
#
# If a school has one officer and it has officers with taser, we can conclude
# that the school has one officer who has a taser. But if a school has three
# officers and a taser, we don't know how many tasers there are.
ssocs00$has_taser <- NA
ssocs04$has_taser <- NA
ssocs06$has_taser <- ssocs06$C0246 == 1
ssocs08$has_taser <- ssocs08$C0246 == 1
ssocs10$has_taser <- ssocs10$C0246 == 1
frss_ssd14$has_taser <- NA
ssocs00$has_spray <- NA
ssocs04$has_spray <- NA
ssocs06$has_spray <- ssocs06$C0248 == 1
ssocs08$has_spray <- ssocs08$C0248 == 1
ssocs10$has_spray <- ssocs10$C0248 == 1
frss_ssd14$has_spray <- NA
ssocs00$has_firearm <- NA
ssocs04$has_firearm <- NA
ssocs06$has_firearm <- ssocs06$C0250 == 1
ssocs08$has_firearm <- ssocs08$C0250 == 1
ssocs10$has_firearm <- ssocs10$C0250 == 1
frss_ssd14$has_firearm <- NA
# "SSOCS": the sum of all surveys
ssocs_columns <- c(
'year',
'weight',
'has_officer',
'n_full_time_officers',
'n_part_time_officers',
'has_taser',
'has_spray',
'has_firearm'
)
ssocs <- rbind(
ssocs00[ssocs_columns],
ssocs04[ssocs_columns],
ssocs06[ssocs_columns],
ssocs08[ssocs_columns],
ssocs10[ssocs_columns],
frss_ssd14[ssocs_columns]
)
ssocs$n <- 1
for (col in c(
'n_full_time_officers',
'n_part_time_officers'
)) {
ssocs[is.na(ssocs[col]),col] <- 0
}
ssocs$has_full_time_officer <- ssocs$n_full_time_officers > 0
ssocs$has_part_time_officer <- ssocs$n_part_time_officers > 0
for (col in names(ssocs)) {
if (col != 'year' && col != 'weight') {
ssocs[paste0(col, '_weighted')] <- ssocs[col] * ssocs$weight
}
}
COPS Office
The Community Oriented Policing Services office supplied us with a summary of all the grants it provided.
This list is only the COPS office, and it's only amounts specifically spent on hiring school resource officers.
This is far from a list of SRO counts by year: COPS is a federal program, and law enforcement budgets are mostly supplied by local/state governments.
In the provided Word document, the grant amounts for 1999-2005 were all asterisked: "Additional funding may have been used to hire SROs under the COPS Office Universal Hiring Program, but was not specifically tracked."
cops_grants <- data.frame(
year=seq(1994, 2015),
amount=c(NA, NA, NA, NA, NA, 159937854, 159903439, 154229248, 158364762, 36613569, 50565923, 5040981, 0, 0, NA, NA, NA, 55109871, 4025463, 46450849, 22541206, 14901904),
n_officers=c(NA, NA, NA, NA, NA, 1403, 1472, 1355, 1373, 311, 426, 41, 0, 0, NA, NA, NA, 238, 31, 370, 167, 128)
)
cops_grants
paste0(
'Total $',
round(sum(cops_grants[!is.na(cops_grants$amount),'amount']) / 1000000, 1),
'M spent to hire ',
sum(cops_grants[!is.na(cops_grants$n_officers),'n_officers']),
' officers'
)
year | amount | n_officers | |
---|---|---|---|
1 | 1994 | NA | NA |
2 | 1995 | NA | NA |
3 | 1996 | NA | NA |
4 | 1997 | NA | NA |
5 | 1998 | NA | NA |
6 | 1999 | 159937854 | 1403 |
7 | 2000 | 159903439 | 1472 |
8 | 2001 | 154229248 | 1355 |
9 | 2002 | 158364762 | 1373 |
10 | 2003 | 36613569 | 311 |
11 | 2004 | 50565923 | 426 |
12 | 2005 | 5040981 | 41 |
13 | 2006 | 0 | 0 |
14 | 2007 | 0 | 0 |
15 | 2008 | NA | NA |
16 | 2009 | NA | NA |
17 | 2010 | NA | NA |
18 | 2011 | 55109871 | 238 |
19 | 2012 | 4025463 | 31 |
20 | 2013 | 46450849 | 370 |
21 | 2014 | 22541206 | 167 |
22 | 2015 | 14901904 | 128 |
Officers in schools
The numbers of school resource officers were given to us upon request by the Bureau of Justice Statistics for SSOCS 2003-2004, 2005-2006, 2007-2008, 2009-2010, from the private-use data files.
to_plot <- data.frame(
year=c(
1997,
2000,
2005,
2006,
2008,
2010,
2014
),
percent_of_schools_with_sro=c(
10, # 1997 FRSS -- includes all law enforcement officers
31.34, # 2000 SSOCS -- includes all security guards, period -- a gross overcount
100*26000/80500, # 2004 SSOCS private-use data file (numerator is # schools with SROs)
100*26900/83200, # 2006 SSOCS private-use data file
100*29400/83000, # 2008 SSOCS private-use data file
100*25700/82800, # 2010 SSOCS private-use data file
30 # 2014 FRSS, as cited in its report
)
)
to_plot
ggplot(to_plot, aes(x=to_plot$year, y=to_plot$percent_of_schools_with_sro)) +
expand_limits(y=0) +
geom_line() +
geom_label(aes(label=round(percent_of_schools_with_sro, 1))) +
ggtitle('Percentage of schools with SRO')
year | percent_of_schools_with_sro | |
---|---|---|
1 | 1997 | 10 |
2 | 2000.00 | 31.34 |
3 | 2005.00000 | 32.29814 |
4 | 2006.00000 | 32.33173 |
5 | 2008.00000 | 35.42169 |
6 | 2010.00000 | 31.03865 |
7 | 2014 | 30 |
Weapons officers are holding
to_plot <- aggregate(
list(
n=ssocs$n_weighted,
n_with_taser=ssocs$has_taser_weighted,
n_with_spray=ssocs$has_spray_weighted,
n_with_firearm=ssocs$has_firearm_weighted
),
by=list(year=ssocs$year),
FUN=sum
)
to_plot <- rbind(
data.frame(year=to_plot$year, group='taser', percent=100 * to_plot$n_with_taser / to_plot$n),
data.frame(year=to_plot$year, group='spray', percent=100 * to_plot$n_with_spray / to_plot$n),
data.frame(year=to_plot$year, group='firearm', percent=100 * to_plot$n_with_firearm / to_plot$n)
)
to_plot <- to_plot[!is.na(to_plot$percent),]
ggplot(to_plot, aes(x=year, y=percent, group=group, colour=group)) +
expand_limits(y=0) +
geom_line() +
geom_label(aes(label=round(to_plot$percent, 2))) +
ggtitle('Percentage of schools with equipment')