This document presents an ongoing investigation into the data available through the FDLE on FDOC Disciplinary actions. (Investigation begun 2023-10-28, it’s still in very rough and preliminary form)
Thank you Max at Community Spring for bringing to my attention that the FDLE collects incarceration data from the Florida Department of Corrections. This investigation will utilize that data, which is available from the Florida Department of Law Enforcement, but I would not recommend looking at the FDLE dashboard because it’s not very useful.
# Packages utilized:
pkgs = c("tidyverse",
"kableExtra",
"DT")
inst = lapply(pkgs, library, character.only = TRUE)
# Initializing Seed
set.seed(8675309)
# Bringing in Data
root <- read.csv("~/pubic_preclean/Incarcerationsupervision_00000.csv") %>%
select("INCARCERATION_SUPERVISION_ID","RACE_CODE","SEX_CODE","ETHNICITY_CODE","INMATE_AGE","AGENCY_NAME", "CUSTODY_ADMISSION_DATE")
disc <- read.csv("~/pubic_preclean/IncarcerationSupervisionDisciplinary_00000.csv") %>%
select("INCARCERATION_SUPERVISION_ID",'INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC',"INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC", "INCAR_SUPERV_CREATED_DATE")
#cleaning data
root$RACE_CODE <- as.factor(root$RACE_CODE)
root$SEX_CODE <- as.factor(root$SEX_CODE)
root$ETHNICITY_CODE <- as.factor(root$ETHNICITY_CODE)
root$AGENCY_NAME <- as.factor(root$AGENCY_NAME)
root$CUSTODY_ADMISSION_DATE <- as.Date(root$CUSTODY_ADMISSION_DATE)
disc$INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC <- as.factor(disc$INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC)
disc$INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC <- as.factor(disc$INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC)
disc$INCAR_SUPERV_CREATED_DATE <- as.Date(disc$INCAR_SUPERV_CREATED_DATE)
So, the FDLE has a table that, once trimmed of all irrelevant data, looks like this: Data on people:
# Just the summary data, mr computer plez
summary(root)
INCARCERATION_SUPERVISION_ID
Min. : 1
1st Qu.:2213570
Median :2575577
Mean :2226684
3rd Qu.:2657504
Max. :2713518
RACE_CODE SEX_CODE
American Indian or Alaska Native: 96 Female: 8285
Asian : 26 Male :94267
Black :46519
Unknown : 5315
White :50596
ETHNICITY_CODE INMATE_AGE
Hispanic or Latino :12322 Min. :18.00
Not Hispanic or Latino:88650 1st Qu.:27.00
Unknown : 1580 Median :34.00
Mean :36.03
3rd Qu.:43.00
Max. :91.00
AGENCY_NAME
CENTRAL FLORIDA RECEPTION CENTER MAIN : 8704
RECEPTION AND MEDICAL CENTER MAIN UNIT : 5555
SOUTH FLORIDA RECEPTION CENTER : 4160
FLORIDA WOMENS RECEPTION CENTER : 3652
NORTHWEST FLORIDA RECEPTION CENTER ANNEX: 3292
BLACKWATER CORRECTIONAL FACILITY : 1936
(Other) :75253
CUSTODY_ADMISSION_DATE
Min. :1960-01-19
1st Qu.:2016-03-31
Median :2021-05-03
Mean :2017-11-03
3rd Qu.:2022-08-02
Max. :2023-09-11
All identifying information has been removed from these data. The supervision ID appears to be a unique FDLE internal identifier.
However, the records do seem to represent the entire population under the supervision or custody of the Florida Department of Corrections.
It appears that they do have every disciplinary action taken against these individuals, just recorded in a separate table.
# now the other one plz mr computer
summary(disc)
INCARCERATION_SUPERVISION_ID
Min. : 26
1st Qu.:2332826
Median :2567680
Mean :2303654
3rd Qu.:2655291
Max. :2713512
INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC
Disciplinary Confinement :208826
Loss of Gain Time : 80764
Cashless Canteen Denial : 36080
Privilege Suspension - Other: 15158
Verbal Reprimand : 13366
Loss of Future Gain Time : 10773
(Other) : 25578
INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC
Disobeying verbal or written order : 45876
Disrespect persons of authority : 27669
Disorderly conduct : 23163
Use of unauthorized drugs : 19929
Fighting : 19082
Unauthorized possession/use of communication device/technology: 18558
(Other) :236268
INCAR_SUPERV_CREATED_DATE
Min. :2022-02-25
1st Qu.:2023-05-17
Median :2023-07-16
Mean :2023-05-24
3rd Qu.:2023-07-16
Max. :2023-09-17
Unfortunately, it appears that the records for disciplinary actions only span a year and a half, from Feburary 2022 to September 2023, but we have 390,545 recorded disciplinary actions altogether.
# All this is for figure 1
fill_order <- c("Disciplinary Confinement", "Loss of Gain Time", "Cashless Canteen Denial","Privilege Suspension - Other","Verbal Reprimand","Loss of Future Gain Time","Disciplinary Squad","Extra Duty","Restitution Payment","Alternative Housing","Privilege Suspension - Mail, Visitation","Privilege Suspension - Visitation","Privilege Suspension - Mail","Restricted Labor Squad","Disciplinary Confinement Part Time")
fill_order <- rev(fill_order)
disc$INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC <- factor(
disc$INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC,
levels = fill_order, ordered = TRUE
)
ggplot(disc, aes(x = reorder(INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC, INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC, function(x) length(x)), fill = INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC)) +
geom_bar() +
scale_fill_manual(values = c(
"Disciplinary Confinement" = "#015F97", "Loss of Gain Time" = "#E47237",
"Cashless Canteen Denial" = "#DDB835", "Privilege Suspension - Other" = "#3F8A24",
"Verbal Reprimand" = "#F0EADC", "Loss of Future Gain Time" = "#C84F68",
"Disciplinary Squad" = "#99C285", "Extra Duty" = "#7C3655",
"Restitution Payment" = "#5D395F", "Alternative Housing" = "#ADA193",
"Privilege Suspension - Mail, Visitation" = "#627F7B", "Privilege Suspension - Visitation" = "#DDAC6D",
"Privilege Suspension - Mail" = "#3F8A24", "Restricted Labor Squad" = "#8D422F",
"Disciplinary Confinement Part Time" = "black"
)) +
xlab("Count of Active FDOC Disciplinary Action") +
ylab("Count") +
ggtitle("Disciplinary Violation Allegations Against FDOC Population Feb 2022- Sep 2023, Colored by Outcome") +
labs(caption = "Figure 1") +
theme_minimal() +
coord_flip() +
theme(
axis.text.y = element_text(hjust = 1, vjust = 0.5, face="bold", size = 12.5),
legend.title = element_blank(),
legend.position = "bottom",
plot.background = element_rect(fill = "#ECE5D8"),
panel.grid.major = element_line(color = "gray", linewidth = 0.2),
panel.grid.minor = element_line(color = alpha("gray", 0.2), size = 1)
)
The plot above displays the counts of rule violation accusations made by FDOC staff against currently incarcerated individuals in the Florida Department of Corrections, and it uses different colors to represent the outcomes of the disciplinary process.
It is important to note that the plot shows the count of rule violations themselves, not the count of individuals who have been charged or faced consequences for these actions. It is common for individuals to be charged with multiple violations for a single action. For example, throwing a tray to the ground can result in charges of both disorderly conduct and destruction of state property. In such cases, a person could expect to be confined for 30 days and lose 30 days of previously-earned gain time, along with whatever else gets thrown at them.
These plots provide valuable information. However, it’s important to consider that when looking at the incidence of outcomes among individuals charged with rule violations, the results may look different. For example, it is likely that nearly 100% of those actually incarcerated (currently this data still includes those on parole, etc.) who have been accused of ‘disorderly conduct’ have ended up in confinement with that charge. The presence of multiple disorderly conduct charges and the concurrent punishments (such as loss of gain time) during confinement is here obscuring the true measure of reliance that FDOC has on confinement.
r_disc <- merge(root %>% select(INCARCERATION_SUPERVISION_ID, RACE_CODE), disc, by = "INCARCERATION_SUPERVISION_ID") %>%
select(-"INCARCERATION_SUPERVISION_ID")
Processing the 104 individual rule violations can be overwhelming. It would be more useful to categorize them into a smaller number of categories. For instance, violations such as ‘disobeying a verbal or written order’, ‘disrespect of someone in authority’, and ‘disorderly conduct’ could be categorized under ‘officer got mad’, along with many others. I will make the rule violation categories now.
doing_time <- c(
"Posession/manufacture of weapons, ammunition or explosives",
"Gang-related activities",
"Posession of unauthorized beverages",
"Theft of property under $50 in value",
"Bartering with others",
"Attempt or conspire to commit crime or violate rules",
"Manufacture of drugs or unauthorized beverages",
"Unauthorized/illegal financial transaction",
"Posession of items facilitating unauthorized/illegal financial transaction",
"Posession of negotiables in unauthorized amounts, forms or location",
"Trafficking in drugs or unauthorized beverages",
"Sex acts or unauthorized physical contact involving inmates",
"Posession of stolen property",
"Theft of property exceeding $50 in value",
"Unauthorized physical contact involving non-inmates",
"Loaning or borrowing money or other valuables",
"Gambling or possession of gambling paraphernalia",
"Fraud or attempted fraud",
"Bribery or attempted bribery",
"Extortion or attempted extortion",
"Self-Mutilation",
"Unauthorized contact in behalf of another inmate",
"Making purchase or contract without approval",
"Consume Intoxicants",
"Tattooing, branding or body art including piercing",
"manufacture of weapons",
"unauthorized beverages",
"Theft of property",
"Possession of negotiables",
"stolen property",
"Canteen Shortage",
"Being in unauthorized area",
"Unauthorized absence from assigned area",
"Possession of escape paraphernalia",
"Unauthorized possession/use of communication device/technology",
"Visiting regulation violations",
"Possession of tobacco-related product by non-death row or non-community release inmate",
"Telephone regulation violations",
"Introduction of any contraband",
"Personal or business relationship with staff member or volunteer",
"Missing count",
"Mail regulation violations",
"Use of Alcohol",
"Possession of unauthorized clothing or linen",
"Escape or escape attempt",
"Failure to proceed to/from designated area",
"Possession of tobacco-related product by death row inmate"
)
drugs <- c("Possession of narcotics/unauthorized drugs and paraphernalia", "Use of unauthorized drugs", "Possession of aromat")
officer_angry <- c("Disobeying verbal or written order", "Creating, participating in or inciting a minor disturbance", "Participating in riots, strikes, mutinous acts or disturbances", "Disorderly conduct", "Disrespect persons of authority", "Refusing to work or participate in mandatory programs", "Disobeying institutional regulations", "Inciting riots, strikes, mutinous acts or disturbances", "Insufficient work", "Wasting State or another property", "Feigning illness or malingering")
violence <- c("Aggravated battery or attempted on correctional officer", "Battery or attempted battery on an inmate", "Aggravated battery or attempted on inmate", "Fighting", "Assault or attempted assault on a correctional officer", "Battery or attempted battery on correctional officer", "Arson or attempted arson", "Assault or attempted assault on an inmate", "Aggravated assault or attempted on inmate", "Battery or attempted battery on staff other than correctional officer", "Aggravated assault or attempted on correctional officer", "Robbery or attempted robbery", "Aggravated battery or attempted on staff other than correctional officer", "Other assault/battery or attempted", "Assault or attempted assault on staff other than correctional officer", "Assault/battery or attempted with deadly weapon", "Battery or attempted on other than staff or inmates", "Assault or attempted assault on other than staff/inmates", "Aggravated assault or attempted on staff other than correctional officer", "Aggravated battery or attempted not on staff/inmates")
misc_rand <- c("Unauthorized use or tampering with computer or office equipment", "Spoken, written or gestured threats", "Destruction of State or another property", "Failure to comply with count procedures", "Tampering/defeating/depriving staff of security device", "Possession of gang-related paraphernalia or material", "Altering/defacing State or another property", "Failure to maintain acceptable hygiene/appearance of housing", "Possession or transfer of other contraband", "Misuse of State or another property", "Lying to staff or falsifying records", "Possession of unauthorized or altered identification", "Refusing to submit to substance abuse testing", "Tampering/defeating any fire or other safety device", "Failure to maintain personal hygiene/appearance", "Tampering/damaging electronic monitoring equipment", "Canteen Shortage over $50", "Failure to deposit earnings", "Destruction of State or another property by gross negligence", "Presenting false testimony or information", "Frivolous, malicious, false information presented to court", "Breaking and entering or attempt", "Canteen Shortage under $50", "Deviating from approved plan", "False property lien", "Failure to remain within designated area of release plan")
sex_related <- c("Lewd or lascivious exhibition", "Obscene or profane act, gesture or statement", "Sexual battery or attempted")
category_mapping <- list(
"Doing Time" = doing_time,
"Drug Violations" = drugs,
"Officer Got Angry" = officer_angry,
"Act of Violence" = violence,
"Misc/Add-On" = misc_rand,
"Sex Related" = sex_related)
# Create a new column for crime categories and initialize it as an empty list
disc$violation_category <- vector('list', length(disc$INCARCERATION_SUPERVISION_ID))
# Loop through categories and apply rules
for (category in names(category_mapping)) {
keywords <- category_mapping[[category]]
matching_indices <- grepl(paste(keywords, collapse = "|"), disc$INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC, ignore.case = TRUE)
# Append the category to the matching entries (instead of overwriting)
disc$violation_category[matching_indices] <- lapply(disc$violation_category[matching_indices], function(x) c(x, category))
}
# If a crime doesn't match any category, set it to "Other"
disc$violation_category[sapply(disc$violation_category, length) == 0] <- "Other"
# All for plot
fill_order <- c("Disciplinary Confinement", "Loss of Gain Time", "Cashless Canteen Denial","Privilege Suspension - Other","Verbal Reprimand","Loss of Future Gain Time","Disciplinary Squad","Extra Duty","Restitution Payment","Alternative Housing","Privilege Suspension - Mail, Visitation","Privilege Suspension - Visitation","Privilege Suspension - Mail","Restricted Labor Squad","Disciplinary Confinement Part Time")
disc %>%
mutate(violation_category = unlist(violation_category)) %>%
ggplot(aes(x = reorder(violation_category, violation_category, function(x) length(x)), fill = INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC)) +
geom_bar() +
scale_fill_manual(values = c(
"Disciplinary Confinement" = "#015F97", "Loss of Gain Time" = "#E47237",
"Cashless Canteen Denial" = "#DDB835", "Privilege Suspension - Other" = "#3F8A24",
"Verbal Reprimand" = "#F0EADC", "Loss of Future Gain Time" = "#000000",
"Disciplinary Squad" = "#99C285", "Extra Duty" = "#7C3655",
"Restitution Payment" = "#5D395F", "Alternative Housing" = "#DF678C",
"Privilege Suspension - Mail, Visitation" = "#627F7B", "Privilege Suspension - Visitation" = "#DDAC6D",
"Privilege Suspension - Mail" = "#3F8A24", "Restricted Labor Squad" = "#8D422F",
"Disciplinary Confinement Part Time" = "#FED95D"
)) +
xlab("Categories of Rule Violation") +
ylab("Count") +
ggtitle("Categories of Disciplinary Violation Allegations Against FDOC Population Feb 2022- Sep 2023, Colored by Outcome") +
labs(caption = "Figure 2", face = 'bold') +
theme_minimal() +
coord_flip() +
theme(
axis.text.y = element_text(hjust = 1, vjust = 0.5, face = "bold", size = 12.5), # Make y-axis text bold
axis.title = element_text(face = "bold"), # Make axis titles bold
legend.title = element_text(face = "bold"), # Make legend title bold
legend.position = "bottom",
plot.title = element_text(face = "bold"), # Make plot title bold
plot.caption = element_text(face = "bold"), # Make caption bold
axis.text.x = element_text(size = 12.5), # Adjust x-axis label size
plot.background = element_rect(fill = "#ECE5D8"),
panel.grid.major = element_line(color = "gray", linewidth = 0.2),
panel.grid.minor = element_line(color = alpha("gray", 0.2), size = 1)
)
Okay now let’s look at it from the other direction – let’s see, of those in confinement, what all they are in for.
# All for plot
conf <- disc %>%
filter(INCARCERATION_DISCIPLINARY_ACTION_TYPE_DESC == 'Disciplinary Confinement') %>%
merge(root %>% select(INCARCERATION_SUPERVISION_ID, RACE_CODE, ETHNICITY_CODE), by = "INCARCERATION_SUPERVISION_ID") %>% select(-"INCARCERATION_SUPERVISION_ID")
conf <- conf %>%
mutate(Race_Ethnicity = ifelse(ETHNICITY_CODE == 'Hispanic or Latino', 'Hispanic or Latino', as.character(RACE_CODE)))
conf$Race_Ethnicity <- as.factor(conf$Race_Ethnicity)
ggplot(conf, aes(x = reorder(INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC, INCARCERATION_DISCIPLINARY_VIOLATION_TYPE_DESC, function(x) length(x)), fill = Race_Ethnicity)) +
geom_bar() +
xlab("Count of Active FDOC Disciplinary Action") +
ylab("Count") +
ggtitle("Disciplinary Violation Allegations Levied Against Currently Incarcerated FDOC Population, Colored by Race") +
labs(caption = "Figure 3", face = 'bold') +
theme_minimal() +
coord_flip() +
theme(
axis.text.y = element_text(hjust = 1, vjust = 0.5, face = "bold", size = 12.5),
legend.title = element_blank(),
legend.position = "bottom",
plot.background = element_rect(fill = "#ECE5D8"),
panel.grid.major = element_line(color = "gray", linewidth = 0.2),
panel.grid.minor = element_line(color = alpha("gray", 0.2), size = 1)
)
# All for plot
conf %>%
mutate(violation_category = unlist(violation_category)) %>%
ggplot(aes(x = reorder(violation_category, violation_category, function(x) length(x)), fill = Race_Ethnicity)) +
geom_bar() +
xlab("Categories of Rule Violation") +
ylab("Count") +
ggtitle("Categories of Disciplinary Violation Allegations Resulting in Disc. Confinement\nFeb 2022 - Sep 2023") +
labs(caption = "Figure 4") +
theme_minimal() +
coord_flip() +
theme(
axis.text.y = element_text(hjust = 1, vjust = 0.5, face = "bold", size = 10.5),
axis.title = element_text(face = "bold"), # Make axis titles bold
legend.title = element_text(face = "bold"), # Make legend title bold
legend.position = "bottom",
plot.title = element_text(face = "bold"), # Make plot title bold
plot.caption = element_text(face = "bold"), # Make caption bold
axis.text.x = element_text(size = 8), # Adjust x-axis label size
plot.background = element_rect(fill = "#ECE5D8"),
panel.grid.major = element_line(color = "gray", linewidth = 0.2),
panel.grid.minor = element_line(color = alpha("gray", 0.2), size = 1)
)
There is still a ton of work remaining for this investigation.