The Florida Department of Corrections hosts a webpage called “Inmate Mortality” on their website; this document is an ONGOING mining of that data. (Status: Ready for Review)
The Florida Department of Corrections hosts a webpage called “Inmate Mortality” on their website. This page lists all deaths that occurred throughout the department during the preceding fiscal year. The webpage provides data for fiscal years 2017-2018 up to the present and can be accessed at Inmate Mortality – Florida Department of Corrections (myflorida.com).
It is remarkable and surprising that the FDOC chose to openly post this data. In my data science training, however, I have learned that data is usually presented in this way only when there is a story to tell or a point to make. By presenting the data in this way, it becomes a communication tool, and one story in partiular has been intentionally centered here by the Florida Department of Corrections: the vast majority of deaths inside are “natural,” which is listed first under “Mortality Facts” and emphasized through the use of a pie chart. The third item in this list of “facts” serves to reinforce this point, and the table of the number of deaths separated by manner of death presented alongside this visual is used as an opportunity to juxtapose the total inmate population. The FDOC’s story is clear: given such a large incarcerated population entering with pre-existing medical conditions, natural deaths are inevitable but slight in comparison to the total number of persons under their care.
“On average, people should be more skeptical when they see numbers. They should be more willing to play around with the data themselves.” – Nate Silver, founder, and editor-in-chief of FiveThirtyEight.
Fortunately, in addition to these summary statistics, the FDOC also posts tables of deaths, and these raw data are quite informative.
Figure 3: Source: Screenshot 2023-09-04 at 12.20.33 PM | Florida Department of Corrections
This paper utilizes these lists for the fiscal years 2015 - present. Although the webpage itself only links to data tables going back to the FY 2017-2018, the FDOC has been publishing said tables since 2015, and links to the fiscal years 2015-16. and 2017-18 were made available to the author via a direct request to the FDOC’s Department of Research and Data.
While many records lack names and the manner of death, the FDOC data does contain 3,497 death observations, each of which is accompanied by a “Date of Death”. The earliest recorded date of death is July 2nd, 2015, and the latest is July 31st, 2023. To begin, I have compiled the data into a sortable and searchable data table.
# Here we are bringing in our csv files -- I copied and pasted the FDOC tables into spreadsheets and saved them
# as csvs. The coordinates of FDOC facilities were manually looked up by me on Google maps.
# base directory for CSV files
base_dir <- "/Users/johnwise/pubic_repository/csvs/fdoc_mortality/"
# Define a function to read and preprocess CSV files
read_and_preprocess_csv <- function(file_path) {
# Read the CSV file
data <- read_csv(file_path, col_names = TRUE, skip = 1, show_col_types = FALSE)
# Extract 'DC Number' using regular expression
data$`DC Number` <- str_extract(data$`DC Number`, "(?<=DCNumber=)[^&]+")
return(data)
}
# Read and preprocess CSV files for each fiscal year
fy15 <- read_and_preprocess_csv(paste0(base_dir, "FY 2015-2016.csv"))
fy16 <- read_and_preprocess_csv(paste0(base_dir, "FY 2016-2017.csv"))
fy17 <- read_and_preprocess_csv(paste0(base_dir, "FY 2017-2018.csv"))
fy18 <- read_and_preprocess_csv(paste0(base_dir, "FY 2018-2019.csv"))
fy19 <- read_and_preprocess_csv(paste0(base_dir, "FY 2019-2020.csv"))
fy20 <- read_and_preprocess_csv(paste0(base_dir, "FY 2020-2021.csv"))
fy21 <- read_and_preprocess_csv(paste0(base_dir, "FY 2021-2022.csv"))
fy22 <- read_and_preprocess_csv(paste0(base_dir, "FY 2022-2023.csv"))
fy23 <- read_and_preprocess_csv(paste0(base_dir, "FY 2023-2024.csv"))
# Brining in Facility coordinates, manually acquired (someone should double check these!) by the author
cords <-read_csv(paste0(base_dir, 'facility_cords.csv'))
# Combine data frames from different fiscal years into one
deaths <- rbind(fy15, fy16, fy17, fy18, fy19, fy20, fy21, fy22, fy23)
# Remove individual fiscal year data frames to free up memory
remove(fy15, fy16, fy17, fy18, fy19, fy20, fy21, fy22, fy23)
# Rename columns for consistency and clarity
colnames(deaths) <- c('Name', 'DCNumber', 'Date_Death', 'FACILITY_description', 'Manner_Death', 'Status')
# Extract the first word from the 'Status' column
deaths$Status <- str_extract(deaths$Status, "^\\S+")
# Convert the 'Date_Death' column to Date format (assuming 'mdy' function from lubridate)
deaths$Date_Death <- as.Date(mdy(deaths$Date_Death))
# Convert selected columns to factor variables for categorical data
deaths$FACILITY_descriptionn <- as.factor(deaths$FACILITY_description)
deaths$Manner_Death <- as.factor(deaths$Manner_Death)
deaths$Status <- as.factor(deaths$Status)
deaths$DCNumber <- as.factor(deaths$DCNumber)
write_csv(deaths, 'deaths1.csv')
# Manner of Death Data Cleaning
deaths$Manner_Death <- recode(deaths$Manner_Death, "Natrual" = "Natural",
"CLOSED" = "Closed",
"4Suicide" = "Suicide",
"Acdident" = "Accident")
# Facilities Data Cleaning
deaths$FACILITY_description <- recode(deaths$FACILITY_description, "Apalachee East" = "APALACHEE EAST UNIT",
"BAKER Re-Entry" = "BAKER RE-ENTRY CENTR",
"Blackwater CF" = "BLACKWATER C.F.",
"CFRC" = "CFRC-MAIN",
"CFRC East" = "CFRC-EAST",
"CFRC South" = "CFRC-SOUTH",
"COLUMBIA C.I." = "COLUMBIA CI",
"Charlotte" = "CHARLOTTE C.I.",
"Cross City" = "CROSS CITY C.I.",
"FSP West" = "FSP WEST UNIT",
"Hamilton Annex" = "HAMILTON ANNEX",
"Hardee" = "HARDEE C.I.",
"Hardee Work Camp" = "HARDEE WORK CAMP",
"LAKE CITY" = "LAKE CITY C.F.",
"Lake" = "LAKE C.I.",
"Marion" = "MARION C.I.",
"Okeechobee" = "OKEECHOBEE C.I.",
"RMC-Main Unit" = "R.M.C.- MAIN UNIT",
"R.M.C.-MAIN UNIT" = "R.M.C.- MAIN UNIT",
"S.F.R.C" = "S.F.R.C.",
"S.F.R.C. SOUTH" = "S.F.R.C. SOUTH UNIT",
"SFRC" = "S.F.R.C.",
"SUMTER C.I." = "SUMTER C.I.",
"Suwannee Annex" = "SUWANNEE C.I. ANNEX",
"Taylor" = "TAYLOR C.I.",
"Union" = "UNION C.I.",
"Wakulla" = "WAKULLA C.I.",
"Wakulla Annex" = "WAKULLA ANNEX",
"Walton" = "WALTON C.I.")
# there are three records for which the cause of death was determined to be 'Undetermined' and three records for
#which this variable was valued as 'Closed'. This "Closed" is meant to be a category for investigative status,
# so for the purposes of this investigation we collapse those categorized as "Closed" to be "Undetermined".
deaths$Manner_Death <- recode(deaths$Manner_Death, "Closed" = "Undetermined")
write_csv(deaths, 'deaths2.csv')
# Creating the table utilizing the data imported and cleaned above
facilities <- deaths %>%
group_by(FACILITY_description, Manner_Death) %>%
summarise(count = n()) %>%
pivot_wider(names_from = Manner_Death, values_from = count, values_fill = 0) %>%
mutate(total = sum(Natural,Suicide, Accident,Homicide,Pending)) %>%
arrange(desc(total))
datatable(facilities, options = list(scrollX = TRUE, pageLength = 10, lengthMenu = c(10, 20, 50)))
write_csv(facilities, 'facilities.csv')
Upon initial examination of the data, it becomes apparent that the majority of deaths occur at the Reception and Medical Center (RMC) in Lake Butler, Florida. This is because the RMC is the secure medical facility for the entire Florida Department of Corrections, and includes a hospital on site where individuals in need of hospitalization or specialty medical care are housed. The facility was founded in 1968 as an intake and processing point for all male state prisoners and as a secure medical facility.
per_month_all2 <- deaths %>%
group_by(FACILITY_description, month = floor_date(Date_Death, unit = "month")) %>%
summarise(Total_month_Deaths = n()) %>%
mutate(Facility_obs_count = sum(Total_month_Deaths))
per_month_rmc_keyed <- per_month_all2 %>% mutate(RMC = FACILITY_description == 'R.M.C.- MAIN UNIT')
ggplot(per_month_rmc_keyed, aes(x = as.Date(month), y = Total_month_Deaths, fill = RMC)) +
geom_rect(aes(xmin = as.Date("2020-03-09"), xmax = as.Date("2021-08-25"), ymin = -Inf, ymax = Inf), fill = "lightpink", alpha = 0.3) +
geom_col() +
scale_x_date(date_labels = "%B, %Y", date_breaks = "6 months") +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
coord_cartesian(xlim = as.Date(c("2015-07-02", "2023-06-29"))) +
xlab(NULL) +
ylab('Count') +
labs(fill = "", title = "Monthly FDOC Deaths -- RMC/Not-RMC:") +
theme(legend.position = "top",
legend.direction = "horizontal",
legend.key.width = unit(1, "cm"),
legend.text = element_text(size = 10),
legend.key = element_rect(fill = c("blue", "lightpink"), color = "gray")) +
scale_fill_manual(values = c("FALSE" = "blue", "TRUE" = "black"),
labels = c("Non Lake Butler RMC Death", "Lake Butler RMC Death")) +
annotate(geom="text", label='2020 COVID 19 Florida Emergency', x=as.Date('2020-12-09'), y=-1.75, size=2.5) +
labs(caption = "Figure 4")
The plot above displays the total number of deaths over time for the period covered by our data. It has been separated into Lake Butler and Non-Lake Butler deaths to better understand the contribution of deaths from Lake Butler and to highlight that the total number of deaths in the Florida Department of Corrections is largely determined by the frequency of deaths at Lake Butler RMC.
In my experience, Lake Butler, Florida is one of the most dangerous sites in the prison system in terms of assaults on the incarcerated population by staff. During my time incarcerated in Florida, I was personally housed at Lake Butler RMC on multiple occasions, due to the medical problems I experienced surrounding my food allergies while incarcerated, and I was there a total of about a year altogether. During that time, I personally witnessed many acts of violence and assault, most from staff members onto the incarcerated population, but equally as often did I see violence among the incarcerated population that was encouraged by a complicit staff.
For example, sometime around 2012, ten years into my sentence, I was sent back to Lake Butler RMC from my facility and was housed at the Main Unit in “I Block” for four months. This building was constructed shortly after the facility was opened. When I first entered the building with my property, I climbed a dark set of stairs. At the top of the flight, however, I found only a set of cell bars blocking the office area beyond the landing. In the office, behind a desk, a Sargent sat chatting with a shift officer. Moreover, on the landing at the top of the stairs, there was only concrete, but a set of footprints was painted onto the floor, facing the cinderblocks and only inches away.
Alone and with no instructions, I stepped into the footprints and stood, nose to the wall and holding my property hanging by my arms at my side. After some time had passed, I heard a laugh and the sergeant say “you can throw him down the stairs if you need to.” That’s when I noticed that my feet had come off the footprints. In a panic, I fixed my feet and glanced behind me to see if I was still in danger. The sergeant had instructed one of his “run around” orderlies (an incarcerated person like myself) to fix my feet for me. Seeing that I’d done so myself, the orderly hesitated, obviously relieved, and the sergeant only laughed. Normally, just looking away from the wall would have been enough to merit violence, so I took his laugh as real evidence that I’d escaped harm by realizing on my own that my feet were misplaced.
I myself ended up working as a runaround, and I worked for that sergeant for about four months. Though I managed to avoid committing violence on his behalf (much to his disappointment), I would not say that those four months were without trauma. Sergeant Moran has since been convicted of plotting to murder a former inmate, along with two other staff members, all of whom have been linked to the racist hate organization, the KKK.
I have seen officers at Lake Butler RMC jumping up and down on incapacitated person’s faces. I have seen grown men slapped open-handed in the face by ‘correctional officers’ at Lake Butler RMC in front of hundreds of other men more times than I can count. I have seen officers at Lake Butler RMC smash a 17 year old child’s face through a pane of security glass (the kind with the wire in it) because of “his attitude”, and the next day they had a piece of paper with a smily face drawn on it taped over the broken glass.
Lake Butler Reception Medical Center is a bad place. For context, consider a similar institution: The Florida School for Boys, also known as the Arthur G. Dozier School for Boys. This reform school operated in the panhandle town of Marianna (equidistant from Talahassee as Lake Butler, but on the opposite side) from January 1, 1900, to June 30, 2011. Throughout its 111-year existence, the school gained a notorious reputation for abuse, assaults, and even student murders by staff members. Despite investigations, leadership changes, and promises of improvement, allegations of cruelty persisted. In 2009, a comprehensive investigation was ordered by the governor after a failed state inspection. Subsequent investigations in 2010 and 2011 substantiated claims of abuse and violence. Consequently, the school was permanently closed in June 2011. A survey by the University of South Florida revealed 55 burials on the school grounds, with most outside the designated cemetery area. The survey also documented nearly 100 deaths at the school.
To me and thousands of Florida citizens, Lake Butler Reception Medical Center represents a still-existent Dozier School, only for adults. The culture and norms that formed and supported the Dozier School are still present at Lake Butler, and it still today continues to act as a site of white racist repression, violence, and hate.
I am greatly saddened that anyone would have to die there, in that nightmare of a place and wholly separated from those they love.
The chart below shows the number of homicides by facility. While it is possible that many of the homicides at Lake Butler RMC are individuals who were attacked at other facilities and then transferred to Lake Butler for medical treatment and subsequently counted as Lake Butler deaths (I’m sure any FDOC official would argue this to be the case), I personally don’t believe that this fully accounts for the entire homicide count at Lake Butler RMC.
violent_FDOC <- deaths %>%
filter(Manner_Death =="Homicide") %>%
mutate(month = floor_date(Date_Death, "week")) %>%
select(Date_Death, FACILITY_description)
ggplot(violent_FDOC, aes(x = reorder(FACILITY_description, FACILITY_description, function(x) length(x)))) +
geom_bar() +
geom_text(aes(label = ..count..), stat = "count", size =3.25, hjust = 1.5, color = "white") +
coord_flip() +
xlab("FDOC Facilities") +
ylab("Homicide Count") +
scale_y_discrete(labels = scales::label_number(scale = 1)) +
ggtitle("FDOC Homicides by Facility July 2015- June 2023") +
labs(caption = "Figure 5")
per_week_all4 <- deaths %>%
filter(Manner_Death== 'Accident') %>%
group_by(week = floor_date(Date_Death, unit = "week")) %>%
summarise(Total_week_Deaths = n())
t_value <- function(data, indices) {
scores <- scores(data[indices], type = "t")
abs(scores)
}
# Bootstrap:
boot_tee <- boot(per_week_all4$Total_week_Deaths, t_value, R = 10000)
per_week_all4$p_values <- 1 - pnorm(boot_tee$t0)
per_week_all4$high <- per_week_all4$p_values<=0.05
ggplot(per_week_all4, aes(x = week, y= Total_week_Deaths, col= high)) +
geom_rect(aes(xmin = as.Date("2020-03-09"), xmax = as.Date("2021-08-25"), ymin = -Inf, ymax = Inf), fill = "lightpink", alpha = 0.7) +
geom_col() +
scale_x_date(date_labels = "%B, %Y", date_breaks = "6 months") +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
coord_cartesian(xlim = as.Date(c("2015-07-02", "2023-06-29"))) +
xlab(NULL) +
ylab('Count of Accidents') +
guides(color='none') +
annotate(geom="text", label='2020 COVID 19 Florida Emergency', x=as.Date('2020-12-09'), y=-.25, size=2.5) +
labs(caption = "Figure 6")
The plot above shows the historical rate of occurrence of accidents resulting in deaths over the entire period covered by our data. To explain the coloration, the scores() algorithm utilizes the historical information available on frequency of accidental deaths to assess the probability of a given week being both ‘usual’ and having as many accidental deaths observed in that week as seen. The weeks that we see above displayed in blue are those weeks in which that calculated probability is less than 5%.
This spate of accidental deaths, it seems, did catch the notice of the Tampa Bay Times. According to the Times, the Florida prison system has long been considered one of the most dangerous in the US, with issues including violence, use-of-force by staff, and problems with delivery of health care. At the time, they reported that the Florida Department of Corrections was investigating the causes of the spike, with an increase in overdoses on synthetic drugs like K2 being pointed to as a possible contributing factor. https://www.tampabay.com/news/politics/Record-number-of-inmates-died-in-Florida-prisons-last-year-And-they-died-younger-than-past-years-_164715214/ I was there, and I will tell you there was nothing to really investigate, the K2 wave that hit the FDOC was insane.
Synthetic cannabinoids, also known as Spice or K2, are human-made chemicals designed to mimic the effects of THC, the primary psychoactive compound found in marijuana. They are often sprayed onto plant material and sold in small packages as a legal alternative to marijuana. The chemicals used to make synthetic cannabinoids are often changing, making them difficult to regulate and control. Synthetic cannabinoids entered the prison system around 2012, but it wasn’t until around 2016 that they became so prevalent that the whole tenor of one’s life for weeks-long cycles could be determined by the quality and caliber of the latest batch to come in.
I’m talking about individuals having seizures on the sidewalks while nurses fail to respond. I’m talking about people lying in piles on the bathroom floor, hidden from sight alongside toilets so that they can smoke, unconscious, and covered in vomit. I’m talking about individuals screaming and thrashing, restrained and tied to their beds, and I’m talking about this happening consistently throughout the day, every day, all over the FDOC.
I used to be addicted to that stuff myself. While I was incarcerated I smoked pot, but if someone in FDOC fails a urine test for THC they would face 60 days of confinement, 180 days of loss of gain time, and a 1-year suspension of visitation rights. So when k2 (synthetic marijuana) entered the prison system, it seemed like a miracle because we could get high without worrying about failing a urine test. Initially, actual k2 and synthetic marijuana were being smuggled in. But as the trend caught on and the underground economy developed, the chemical compounds in the “spice” started to change significantly. I believe I was the first person at the facility I was in to have a seizure (also known as “twack out”) and spend the night at an outside hospital, but I wasn’t the last. The chemicals just kept getting more dangerous, and likely still are.
These are the words of my currently incarcerated friend, John Kingham:
The first wave of the synthetics hit Hardee and FDOC around 2010, and consisted of constantly changing batches of K2. The attraction was that it wouldn’t by show up on piss tests, and that still applies, but over the years any number of new recipes have come and gone, many of them lethal. The infamous Yellow Jacket was exactly that: potpourri sprayed with Black Flag Yellow Jacket and Wasp Spray. It was insanely addictive, wrecked one’s digestion, and was easy to make.
The hardest part of the twack show to absorb is the way it renders all dorms (save program dorms, and even then, depending on the strictness of the camp) into hellscapes of people moaning and shrieking, vomiting, pulling off their clothes, gibbering like baboons, or running for help from demons only they can see, all this around the clock. As long as there’s dope there are going to be folks slumped. We’re getting a break because for the first time in three months the camp has run dry. That’s no exaggeration.
The other insidious quality is how addictive it is to be incoherent all day every day. The fiendish attraction lies in the substitution of oblivion for hope or goals or ambition, and this in turn marks what to my Catholic eye is the incursion of the truly demonic. For what is the greatest lie that the Father of Lies whispers into our ears? Abandon hope. Your life is worthless. You may as well get high. This plays well with understaffed staff who’d rather not try to run rec or canteen or programs, keeping you inside all day every day, which is what we have going on here. And elsewhere. Until Tomoka got the incentivized money, it had gotten back to no rec for a week or ten days, and only for fifteen or twenty minutes if then, so they could put it on the books that they’d run it. Complicity in the drug trade as a management tool. How cynical and vile.
The second wave of synthetics that changed the system is the various powders, esp. molly and ice. They’re analogs of the methamphetamine family and will show up on piss tests, but they’re definitely different that the typical glass-looking ice that I used to see from the Mexican sets. Molly has singlehandedly run the price of tobacco into the stratosphere, with a single cigarette going for twenty-five bucks because the bangers like to smoke molly all night on tobacco in order to heat it up enough to work its alchemical magic. It’s a chaser drug to rival crack, but without the apocalyptic rush of the latter. As a corollary, two hundred dollar packs of cigarettes are an obvious incentive to staff misbehavior and an easy pitch, since most use tobacco already. Snuff is up to seventy five a can and they smoke it too, with or without the spit soaking.
The ice is more of a white boy thing, made to eat or snort or occasionally shoot. The difference is that it’s tank-grown, like those salt or sugar crystals we used to make on a string as kids in science class. The potency is decent, but the longterm buzz is dialed back so the need to re-up is more constant. You can get pretty ganked up on it, but not the heart-stopping pounding that old-school crank or real ice gives. Because of the costs the dope boys are the ones who mostly use the powders, so you can see and smell who’s doing what with just a glance at their demeanors.
All in all, these new drugs have changed the whole face of the system, but the human degradation caused by the smoke is the most horrible to watch. I can personally attest after twelve years of use and a decent period of (by no means guaranteed) sobriety that the worst sort of thoughts overcame me whenever I smoked, but I was so high that I didn’t care. Whenever I’m locked in for a few days the itch gets pretty bad, but I’m usually able to resist precisely because I now see what havoc it plays on my state of mind. Kids, definitely don’t try this at home. :-(
…
Hi John: The second part of your 10/26 kite came in just after I launched my reply. I like what you wrote, although if I got it intact, the intro is a little flat. I’m not totally sold on the repetition in the second paragraph, stylistically. I almost forgot the following episode:
‘When I went to Wakulla Annex on an extended hurricane evacuation in late 2016, I first encountered fentanyl-laced K2. It looked like typical red dope, but that’s a common tactic to piggyback on the success of other recipes: imitate the latest color scheme by dying your product with similar food coloring. Within three days of first smoking it I woke up ’dopesick’, i.e. showing the classic signs of narcotic withdrawal pains: the signature runny itchy nose, stomach doing backflips, chills, and the certainty that only another sack would makes me feel human again. I should have suspected something when a whole cell full of smokers would share one joint, then slump in place for three hours instead of the usual half hour or so. The only logical explanation from an economic POV? It was sprayed with cheap Chinese fentanyl, or the even more lethal veterinary variant carfentanyl, eight times the strength of fentanyl. (Check sp.- possibly carfentanil) Those were the most hellish withdrawals I ever experienced.’How those drugs get in is beyond the scope of this investigation (the officers bring it in – I mean, sure, they find a few little packages coming in through visitations always, but officers bring in POUNDS).
accidents_FDOC <- deaths %>% filter(Manner_Death == 'Accident')
ggplot(accidents_FDOC, aes(x = reorder(FACILITY_description, FACILITY_description, function(x) length(x)))) +
geom_bar() +
geom_text(aes(label = ..count..), stat = "count", size =3.25, hjust = 1.5, color = "white") +
coord_flip() +
xlab("FDOC Facilities") +
ylab("Fatal Accident Count") +
ggtitle("Fatal FDOC Accidents by Facility July 2015- June 2023") +
labs(caption = "Figure 7")
I would say, yes, those are the facilites with the worst k2 problems. Someone should certainly double-check all those RMC ‘accidents’ though, particularly ones where incarcerated persons ‘fell down stairs’.
per_week_natural <- deaths %>%
filter(Manner_Death == 'Natural') %>%
group_by(week = floor_date(Date_Death, unit = "week")) %>%
summarise(Total_week_Deaths = n())
t_value <- function(data, indices) {
scores <- scores(data[indices], type = "t")
abs(scores)
}
# Bootstrap:
boot_t <- boot(per_week_natural$Total_week_Deaths, t_value, R = 10000)
per_week_natural$p_values <- pnorm(boot_t$t0, lower.tail = FALSE)
per_week_natural$high <- per_week_natural$p_values<=0.05
ggplot(per_week_natural, aes(x = week, y= Total_week_Deaths, col= high)) +
geom_rect(aes(xmin = as.Date("2020-03-09"), xmax = as.Date("2021-08-25"), ymin = -Inf, ymax = Inf), fill = "lightpink", alpha = 0.7) +
geom_col() +
scale_x_date(date_labels = "%B, %Y", date_breaks = "6 months") +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
coord_cartesian(xlim = as.Date(c("2015-07-02", "2023-06-29"))) +
xlab(NULL) +
ylab('Count') +
guides(color='none') +
annotate(geom="text", label='2020 COVID 19 Florida Emergency', x=as.Date('2020-12-09'), y=-1.75, size=2.5) +
ggtitle(label = 'FDOC Natural Deaths, June 2015 -July 2023') +
labs(caption = "Figure 8")
Here we have a plot of the rate of natural deaths over the time period covered by our data. Once again, the weeks where the calculated probability of observing a result as extreme as the one seen is less than 5%. While it’s acknowledged that the pandemic has disrupted the normalcy of mortality rates, leading to a skewed baseline for expected deaths, this actually strengthens our case that the results here obtained using scores() are all the more salient and deserving of urgent attention, as the pandemic-induced distortions - resulting in a less sensitive scores() test - imply that any weeks yielding high scores are indicative of mortality rates that stand out as unusual even in the context of the pandemic.
The following weeks, filtered to exclude weeks during the 2020-2021 COVID emergency in Florida, stand out as exceptional in the FDOC with regards to the amount of natural deaths. While I refrain from positing any definitive explanations for why these particular facilities experienced heightened instances of natural deaths, I present this information as a potential avenue for future investigations by interested parties. The identification of any genuine causal relationships is of paramount interest, not only to the families who have lost loved ones during their incarceration but also to society at large, for a myriad of compelling reasons.
week | Total_week_Deaths | p_values |
---|---|---|
2015-11-01 | 12 | 0.0423780 |
2016-03-06 | 12 | 0.0423780 |
2017-08-06 | 12 | 0.0423780 |
2017-09-03 | 12 | 0.0423780 |
2017-11-12 | 12 | 0.0423780 |
2017-12-31 | 13 | 0.0208790 |
2019-01-13 | 14 | 0.0093996 |
2019-01-27 | 13 | 0.0208790 |
2019-07-07 | 12 | 0.0423780 |
2020-02-02 | 13 | 0.0208790 |
2021-09-19 | 14 | 0.0093996 |
2021-10-24 | 12 | 0.0423780 |
2021-12-05 | 12 | 0.0423780 |
2022-01-02 | 12 | 0.0423780 |
2023-02-19 | 13 | 0.0208790 |
In the following analysis, we examine maps of groups of facilities that experienced months with statistically significant natural death counts. The plots that follow show all facilities that had at least one death during the respective month. The size and color of the markers correspond to the p-value, which represents the likelihood of observing such a high value for that facility based on its individual historical death data. Less likely results are plotted larger and redder than death counts that are more typical for that facility. You can see the labels for the facilities by hovering over the individual map markers.
While it is valid to compare the p-values across maps by observing the size of the markers, it is not valid to compare colorations across maps at this time. This is because the colors of each map cover the spectrum of their respective associated data entries. Please note that this is a coding issue that I hope to fix soon.
per_month_natural2 <- deaths %>%
filter(Manner_Death == 'Natural') %>%
group_by(FACILITY_description, month = floor_date(Date_Death, unit = "month")) %>%
summarise(Total_month_naturalDeaths = n())
t_value <- function(data, indices) {
scores <- scores(data[indices], type = "t")
abs(scores)
}
per_month_natural2 <- per_month_natural2 %>%
group_by(FACILITY_description) %>%
mutate(
t_values = boot(Total_month_naturalDeaths, t_value, R = 1000)$t0, # Get t-values
p_values = pnorm(t_values, lower.tail = FALSE),
high = p_values <= 0.05
)
per_month_natural2$FACILITY_description <- as.factor(per_month_natural2$FACILITY_description)
summary_data1 <- per_month_natural2 %>%
group_by(month) %>%
arrange(month) %>%
select(-high) %>%
mutate(group_index = row_number())
summary_data2 <- summary_data1 %>%
summarize(
FACILITY_description = paste(FACILITY_description, collapse = ", "),
Total_month_naturalDeaths = sum(Total_month_naturalDeaths)
)
summary_data3 <- summary_data2 %>% select(-Total_month_naturalDeaths)
generate_group_names <- function(group_indices) {
group_names <- character(length(group_indices))
current_group <- 1
for (i in seq_along(group_indices)) {
if (group_indices[i] == 1) {
current_group <- current_group + 1
}
group_names[i] <- paste("Group", current_group-1)
}
return(group_names)
}
summary_data1$group_names <- generate_group_names(summary_data1$group_index)
groupz <- summary_data1
groupz2 <- merge(groupz, cords, by = 'FACILITY_description') %>% arrange(month)
interesting_groups <- groupz2 %>%
filter(!(month >= as.Date("2020-03-09") & month <= as.Date("2021-08-25")))
weeks_of_interest_mult <- unique(interesting_groups$month)
interest <- per_month_natural2 %>%
filter(month %in% weeks_of_interest_mult)
interest$p_values <- ifelse(is.na(interest$p_values) | is.nan(interest$p_values), 0.5, interest$p_values)
interesting <- merge(interest, cords[seq(1,138),], by = 'FACILITY_description') %>% arrange(month) %>% filter(p_values<=0.33)
interesting$p_values[interesting$p_values == 0] <- 1e-6
interesting$high[is.na(interesting$high)] <- FALSE
mapping_naturals <- function(date) {
data <- interesting %>% filter(month == date)
manners <- deaths %>%
filter(month(Date_Death) == month(as.Date(date)) & year(Date_Death) == year(as.Date(date))) %>%
group_by(FACILITY_description, Manner_Death) %>%
summarise(count = n()) %>%
pivot_wider(names_from = Manner_Death, values_from = count, values_fill = 0) %>%
select(FACILITY_description, everything())
# Define a continuous color palette
palette_name <- "YlOrRd"
num_colors <- 9
colors <- brewer.pal(n = num_colors, name = palette_name)[(num_colors / 2 + 1):num_colors]
pal <- colorNumeric(palette = colors, domain = sqrt(sqrt(1/data$p_values)))
leaflet(data) %>%
addTiles(urlTemplate = "https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}",
options = tileOptions(minZoom = 1, maxZoom = 19)) %>%
addCircleMarkers(
radius = ~log(1/p_values)*3,
color = ~pal((1/p_values)^(1/4)),
fillOpacity = .45,
stroke = TRUE,
label = ~paste("Facility:\n", FACILITY_description, "# Deaths: ", Total_month_naturalDeaths, "P_value:", round(p_values, 3))
) %>%
addControl(
position = "bottomleft",
html = paste0("<b style='font-size: 28px;'>", format(as.Date(date), "%B %Y"), "</b>")
) %>%
setView(lng = -84, lat = 28.3, zoom = 6.5)
}
create_kable_table <- function(date) {
kable(interesting %>% filter(month == as.Date(date)) %>% select(FACILITY_description,Total_month_naturalDeaths,p_values,high) %>% arrange(p_values)) %>%
kable_styling(latex_options = "hold_position")
}
high_facilities_facet_plotter <- function(block, high_frame, frame){
facilities_high <- high_frame %>% filter(month == as.Date(block) & high == TRUE) %>% select(1)
facilities_data <- merge(frame, facilities_high, by = 'FACILITY_description') %>% select(FACILITY_description, month, Total_month_naturalDeaths, p_values, high)
block_date <- ymd(block)
xmax_date <- block_date + days(30)
ggplot(facilities_data, aes(x = month, y = Total_month_naturalDeaths, fill = high)) +
geom_rect(aes(xmin = block_date, xmax = block_date + days(30), ymin = -Inf, ymax = Inf), fill = "yellow", alpha = 0.7) +
geom_bar(stat = "identity") +
facet_wrap(~FACILITY_description, ncol = 1, strip.position = "top") + # Labels on the top doesn't work!
theme_minimal() +
scale_x_date(limits = as.Date(c("2015-07-01", "2023-08-01"), format = "%Y-%m-%d")) +
theme(
panel.border = element_rect(color = "black", fill = NA, linewidth = 2), # Add black borders
panel.spacing = unit(0.5, "lines"), # Adjust spacing between panels
strip.text = element_text(face = "bold") # Bolden the strip labels
) +
guides(fill = FALSE) +
facet_grid(FACILITY_description ~ ., scales = "free_y")
}
mapping_naturals('2015-12-01')
high_facilities_facet_plotter('2015-12-01', interesting, per_month_natural2)
create_kable_table('2015-12-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
APALACHEE EAST UNIT | 2 | 0.0065563 | TRUE |
CHARLOTTE C.I. | 2 | 0.0437882 | TRUE |
UNION C.I. | 3 | 0.1119706 | FALSE |
DADE C.I. | 1 | 0.2437312 | FALSE |
S.F.R.C. | 4 | 0.2473894 | FALSE |
ZEPHYRHILLS C.I. | 1 | 0.2655688 | FALSE |
CFRC-SOUTH | 1 | 0.3148651 | FALSE |
mapping_naturals('2016-01-01')
high_facilities_facet_plotter('2016-01-01', interesting, per_month_natural2)
create_kable_table('2016-01-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
SUMTER C.I. | 3 | 0.0000000 | TRUE |
S.F.R.C. | 7 | 0.0062986 | TRUE |
SOUTH BAY C.F. | 2 | 0.1458386 | FALSE |
DADE C.I. | 1 | 0.2437312 | FALSE |
COLUMBIA CI | 1 | 0.2635446 | FALSE |
R.M.C.- MAIN UNIT | 14 | 0.2776935 | FALSE |
mapping_naturals('2016-02-01')
high_facilities_facet_plotter('2016-02-01', interesting, per_month_natural2)
create_kable_table('2016-02-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
LAKE C.I. | 2 | 0.0017074 | TRUE |
LOWELL ANNEX | 2 | 0.0032295 | TRUE |
CHARLOTTE C.I. | 2 | 0.0437882 | TRUE |
R.M.C.- MAIN UNIT | 6 | 0.1183074 | FALSE |
ZEPHYRHILLS C.I. | 1 | 0.2655688 | FALSE |
S.F.R.C. | 2 | 0.3184662 | FALSE |
mapping_naturals('2016-06-01')
high_facilities_facet_plotter('2016-06-01', interesting, per_month_natural2)
create_kable_table('2016-06-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
GULF C.I.- ANNEX | 3 | 0.0000039 | TRUE |
NWFRC MAIN UNIT. | 2 | 0.0000133 | TRUE |
FLORIDA STATE PRISON | 1 | 0.2909945 | FALSE |
mapping_naturals('2016-07-01')
high_facilities_facet_plotter('2016-07-01', interesting, per_month_natural2)
create_kable_table('2016-07-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
S.F.R.C. | 8 | 0.0008072 | TRUE |
R.M.C.- MAIN UNIT | 20 | 0.0256976 | TRUE |
CHARLOTTE C.I. | 2 | 0.0437882 | TRUE |
COLUMBIA CI | 1 | 0.2635446 | FALSE |
CFRC-SOUTH | 1 | 0.3148651 | FALSE |
mapping_naturals('2018-01-01')
high_facilities_facet_plotter('2018-01-01', interesting, per_month_natural2)
create_kable_table('2018-01-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
HARDEE C.I. | 2 | 0.0000000 | TRUE |
R.M.C.- MAIN UNIT | 21 | 0.0145103 | TRUE |
EVERGLADES C.I. | 2 | 0.0623552 | FALSE |
S.F.R.C. | 1 | 0.1458813 | FALSE |
ZEPHYRHILLS C.I. | 2 | 0.2137894 | FALSE |
SUWANNEE C.I. ANNEX | 1 | 0.2493597 | FALSE |
OKALOOSA C.I. | 1 | 0.3047617 | FALSE |
CFRC-SOUTH | 1 | 0.3148651 | FALSE |
UNION C.I. | 1 | 0.3183153 | FALSE |
mapping_naturals('2018-02-01')
high_facilities_facet_plotter('2018-02-01', interesting, per_month_natural2)
create_kable_table('2018-02-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
EVERGLADES C.I. | 3 | 0.0000206 | TRUE |
FLORIDA STATE PRISON | 2 | 0.0477904 | TRUE |
R.M.C.- MAIN UNIT | 15 | 0.2084379 | FALSE |
ZEPHYRHILLS C.I. | 2 | 0.2137894 | FALSE |
COLUMBIA CI | 1 | 0.2635446 | FALSE |
WAKULLA C.I. | 1 | 0.2665919 | FALSE |
TOMOKA C.I. | 1 | 0.2779592 | FALSE |
S.F.R.C. | 2 | 0.3184662 | FALSE |
mapping_naturals('2018-03-01')
high_facilities_facet_plotter('2018-03-01', interesting, per_month_natural2)
create_kable_table('2018-03-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
MOORE HAVEN C.F. | 2 | 0.0001038 | TRUE |
CHARLOTTE C.I. | 2 | 0.0437882 | TRUE |
S.F.R.C. | 1 | 0.1458813 | FALSE |
COLUMBIA CI | 1 | 0.2635446 | FALSE |
ZEPHYRHILLS C.I. | 1 | 0.2655688 | FALSE |
R.M.C.- MAIN UNIT | 14 | 0.2776935 | FALSE |
CFRC-SOUTH | 1 | 0.3148651 | FALSE |
mapping_naturals('2018-05-01')
high_facilities_facet_plotter('2018-05-01', interesting, per_month_natural2)
create_kable_table('2018-05-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
SANTA ROSA C.I. | 2 | 0.0022315 | TRUE |
CFRC-SOUTH | 3 | 0.0061753 | TRUE |
DADE C.I. | 3 | 0.1716340 | FALSE |
S.F.R.C. | 4 | 0.2473894 | FALSE |
UNION C.I. | 1 | 0.3183153 | FALSE |
mapping_naturals('2018-10-01')
high_facilities_facet_plotter('2018-10-01', interesting, per_month_natural2)
create_kable_table('2018-10-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
MOORE HAVEN C.F. | 2 | 0.0001038 | TRUE |
TOMOKA C.I. | 2 | 0.0483658 | TRUE |
S.F.R.C. | 1 | 0.1458813 | FALSE |
CFRC-SOUTH | 1 | 0.3148651 | FALSE |
mapping_naturals('2019-01-01')
high_facilities_facet_plotter('2019-01-01', interesting, per_month_natural2)
create_kable_table('2019-01-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
MARION C.I. | 2 | 0.0013499 | TRUE |
R.M.C.- MAIN UNIT | 23 | 0.0038553 | TRUE |
S.F.R.C. | 7 | 0.0062986 | TRUE |
CFRC-MAIN | 2 | 0.0100372 | TRUE |
ZEPHYRHILLS C.I. | 1 | 0.2655688 | FALSE |
WAKULLA C.I. | 1 | 0.2665919 | FALSE |
FLORIDA STATE PRISON | 1 | 0.2909945 | FALSE |
mapping_naturals('2016-07-01')
high_facilities_facet_plotter('2019-07-01', interesting, per_month_natural2)
create_kable_table('2019-07-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
NWFRC MAIN UNIT. | 2 | 0.0000133 | TRUE |
LIBERTY C.I. | 2 | 0.0022543 | TRUE |
CFRC-SOUTH | 2 | 0.1734046 | FALSE |
ZEPHYRHILLS C.I. | 1 | 0.2655688 | FALSE |
mapping_naturals('2020-02-01')
high_facilities_facet_plotter('2020-02-01', interesting, per_month_natural2)
create_kable_table('2020-02-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
WAKULLA C.I. | 3 | 0.0156169 | TRUE |
R.M.C.- MAIN UNIT | 19 | 0.0430577 | TRUE |
BLACKWATER C.F. | 2 | 0.3070776 | FALSE |
NWFRC ANNEX. | 1 | 0.3126782 | FALSE |
mapping_naturals('2021-09-01')
high_facilities_facet_plotter('2021-09-01', interesting, per_month_natural2)
create_kable_table('2021-09-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
SOUTH BAY C.F. | 4 | 0.0000000 | TRUE |
LAKE C.I. | 2 | 0.0017074 | TRUE |
ZEPHYRHILLS C.I. | 3 | 0.0096387 | TRUE |
BLACKWATER C.F. | 3 | 0.0716758 | FALSE |
SUWANNEE C.I. ANNEX | 1 | 0.2493597 | FALSE |
WAKULLA C.I. | 1 | 0.2665919 | FALSE |
NWFRC ANNEX. | 1 | 0.3126782 | FALSE |
CFRC-SOUTH | 1 | 0.3148651 | FALSE |
UNION C.I. | 1 | 0.3183153 | FALSE |
mapping_naturals('2021-10-01')
high_facilities_facet_plotter('2021-10-01', interesting, per_month_natural2)
create_kable_table('2021-10-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
LIBERTY C.I. | 2 | 0.0022543 | TRUE |
ZEPHYRHILLS C.I. | 3 | 0.0096387 | TRUE |
NWFRC ANNEX. | 2 | 0.0195322 | TRUE |
DADE C.I. | 4 | 0.0354768 | TRUE |
R.M.C.- MAIN UNIT | 7 | 0.1687493 | FALSE |
S.F.R.C. | 4 | 0.2473894 | FALSE |
SUWANNEE C.I. ANNEX | 1 | 0.2493597 | FALSE |
WAKULLA C.I. | 1 | 0.2665919 | FALSE |
UNION C.I. | 1 | 0.3183153 | FALSE |
mapping_naturals('2021-12-01')
high_facilities_facet_plotter('2021-12-01', interesting, per_month_natural2)
create_kable_table('2021-12-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
CFRC-MAIN | 2 | 0.0100372 | TRUE |
SUWANNEE C.I. ANNEX | 3 | 0.0238739 | TRUE |
BLACKWATER C.F. | 3 | 0.0716758 | FALSE |
S.F.R.C. | 5 | 0.1022691 | FALSE |
WAKULLA C.I. | 1 | 0.2665919 | FALSE |
R.M.C.- MAIN UNIT | 9 | 0.3034877 | FALSE |
CFRC-SOUTH | 1 | 0.3148651 | FALSE |
UNION C.I. | 1 | 0.3183153 | FALSE |
mapping_naturals('2022-01-01')
high_facilities_facet_plotter('2022-01-01', interesting, per_month_natural2)
create_kable_table('2022-01-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
COLUMBIA CI | 3 | 0.0200604 | TRUE |
SUWANNEE C.I. ANNEX | 3 | 0.0238739 | TRUE |
WAKULLA C.I. | 2 | 0.2412834 | FALSE |
GULF C.I. | 1 | 0.2427494 | FALSE |
DADE C.I. | 1 | 0.2437312 | FALSE |
R.M.C.- MAIN UNIT | 9 | 0.3034877 | FALSE |
NWFRC ANNEX. | 1 | 0.3126782 | FALSE |
mapping_naturals('2022-04-01')
high_facilities_facet_plotter('2022-04-01', interesting, per_month_natural2)
create_kable_table('2022-04-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
SANTA ROSA C.I. | 2 | 0.0022315 | TRUE |
LOWELL ANNEX | 2 | 0.0032295 | TRUE |
OKALOOSA C.I. | 2 | 0.0288898 | TRUE |
R.M.C.- MAIN UNIT | 8 | 0.2308035 | FALSE |
DADE C.I. | 1 | 0.2437312 | FALSE |
mapping_naturals('2022-09-01')
high_facilities_facet_plotter('2022-09-01', interesting, per_month_natural2)
create_kable_table('2022-09-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
APALACHEE EAST UNIT | 2 | 0.0065563 | TRUE |
SUWANNEE C.I. ANNEX | 3 | 0.0238739 | TRUE |
WAKULLA C.I. | 1 | 0.2665919 | FALSE |
R.M.C.- MAIN UNIT | 14 | 0.2776935 | FALSE |
UNION C.I. | 1 | 0.3183153 | FALSE |
mapping_naturals('2022-12-01')
high_facilities_facet_plotter('2022-12-01', interesting, per_month_natural2)
create_kable_table('2022-12-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
FL.WOMENS RECPN.CTR | 2 | 0.0000000 | TRUE |
ZEPHYRHILLS C.I. | 3 | 0.0096387 | TRUE |
CFRC-MAIN | 2 | 0.0100372 | TRUE |
COLUMBIA CI | 1 | 0.2635446 | FALSE |
SUWANNEE C.I. ANNEX | 2 | 0.2727609 | FALSE |
TOMOKA C.I. | 1 | 0.2779592 | FALSE |
mapping_naturals('2023-02-01')
high_facilities_facet_plotter('2023-02-01', interesting, per_month_natural2)
create_kable_table('2023-02-01')
FACILITY_description | Total_month_naturalDeaths | p_values | high |
---|---|---|---|
MARION C.I. | 2 | 0.0013499 | TRUE |
OKALOOSA C.I. | 2 | 0.0288898 | TRUE |
DADE C.I. | 1 | 0.2437312 | FALSE |
SUWANNEE C.I. ANNEX | 1 | 0.2493597 | FALSE |
ZEPHYRHILLS C.I. | 1 | 0.2655688 | FALSE |
UNION C.I. | 1 | 0.3183153 | FALSE |
The Florida Department of Corrections provides access to its OBIS database for public download here.
This database is separate from the mortality lists utilized throughout this document. I will create a separate post for investigation of general OBIS data soon; however, I am including some data from it in this document to further our consideration of the FDOC’s handling of what I believe to be accidental deaths from overdose.
If you visit the OBIS database, you will find a set of tables that pertain to every person ever recorded as released from the FDOC.
Interestingly, individuals who have died in the custody of the FDOC seem to have been ‘released’ in this manner, at least after approximately 1996.
x <- 10
base_dir <- "/Users/johnwise/Downloads"
# Data Import
Root <- read_excel(paste0(base_dir, "/Inmate_Release (3).XLSX"))
obis_deaths <- Root %>% filter(releasedateflag_descr == 'deceased') %>% select(DCNumber, releasedateflag_descr, PrisonReleaseDate)
obis_deaths %>%
head(x) %>%
kable(caption = paste("Omitting", dim(obis_deaths)[1]-x, "rows for display")) %>%
kable_styling(latex_options = "hold_position")
DCNumber | releasedateflag_descr | PrisonReleaseDate |
---|---|---|
000001 | deceased | 2005-04-24 |
000062 | deceased | 2014-12-09 |
000198 | deceased | 2013-06-27 |
000329 | deceased | 2014-08-29 |
000418 | deceased | 2013-05-13 |
000517 | deceased | 2008-12-12 |
000645 | deceased | 2005-08-14 |
000741 | deceased | 2023-05-14 |
000791 | deceased | 2020-05-30 |
000828 | deceased | 2010-10-17 |
ggplot(obis_deaths, aes(x = as.Date(PrisonReleaseDate))) +
geom_bar(stat = "count", width = 30, fill = "steelblue") + # Adjust the width as needed
scale_x_date(date_breaks = "6 months", date_labels = "%b %Y") +
labs(x = "Date of Prison Release", y = "Count", title = "Monthly Distribution of PrisonReleaseDate dates for persons coded 'deceased'") +
theme_minimal() + # Use a minimal theme
theme(axis.text.x = element_text(angle = 60, hjust = 1)) + # Rotate x-axis labels for better readability
coord_cartesian(xlim = as.Date(c("1990-01-01", "2023-07-31")), ylim = c(0, 200))
Looks odd, right? Let’s Zoom in.
ggplot(obis_deaths, aes(x = as.Date(PrisonReleaseDate))) +
geom_bar(stat = "count", width = 30, fill = "steelblue") + # Adjust the width as needed
scale_x_date(date_breaks = "6 months", date_labels = "%b %Y") +
labs(x = "Date of Prison Release", y = "Count", title = "PrisonReleaseDate dates for persons coded 'deceased', (2015-01-01 - 2023-07-31)") +
theme_minimal() + # Use a minimal theme
theme(axis.text.x = element_text(angle = 60, hjust = 1)) + # Rotate x-axis labels for better readability
coord_cartesian(xlim = as.Date(c("2015-01-01", "2023-07-31")), ylim = c(0, 200))
Looks even more strange here, I’m going to zoom in some more – the top of that big spike is just going to get cut off but we need to see more granular.
ggplot(obis_deaths, aes(x = as.Date(PrisonReleaseDate))) +
geom_bar(stat = "count", width = 90, fill = "steelblue") + # Adjust the width as needed
scale_x_date(date_breaks = "6 months", date_labels = "%b %Y") +
labs(x = "Date of Prison Release", y = "Count", title = "PrisonReleaseDate dates persons 'deceased', (2015-01-01 - 2023-07-31), ymax=25") +
theme_minimal() + # Use a minimal theme
theme(axis.text.x = element_text(angle = 60, hjust = 1)) + # Rotate x-axis labels for better readability
coord_cartesian(xlim = as.Date(c("2016-06-01", "2023-07-31")), ylim = c(0, 25))
The spike and gap in the timeline of deaths stand out to me. These anomalies are clearly noticeable when compared to the list of deaths in the Inmate Mortality data used throughout the rest of this document.
To further investigate this discrepancy, we will merge this peculiar dataset of PrisonReleaseDate dates with the aforementioned data. Then, we will calculate the differences in dates for each observation that matches by DCNumber.
# Calculating Date Differences
data <- merge(deaths, obis_deaths, by = 'DCNumber') %>%
select(-Name, -releasedateflag_descr, -FACILITY_descriptionn) %>%
mutate(
Date_Death = as.Date(Date_Death),
PrisonReleaseDate = as.Date(PrisonReleaseDate),
Days_Between = as.numeric(PrisonReleaseDate - Date_Death)
) %>%
select(Date_Death, PrisonReleaseDate, Days_Between, Manner_Death)
data %>%
head(x) %>%
kable(caption = paste("Omitting", dim(data)[1]-x, "rows for display")) %>%
kable_styling(latex_options = "hold_position")
Date_Death | PrisonReleaseDate | Days_Between | Manner_Death |
---|---|---|---|
2023-05-08 | 2023-05-14 | 6 | Natural |
2020-05-29 | 2020-05-30 | 1 | Natural |
2019-06-04 | 2019-06-05 | 1 | Natural |
2015-11-27 | 2015-11-28 | 1 | Natural |
2016-06-15 | 2016-06-16 | 1 | Natural |
2017-07-06 | 2017-07-07 | 1 | Natural |
2019-07-21 | 2019-07-22 | 1 | Natural |
2020-04-09 | 2020-04-10 | 1 | Natural |
2019-04-07 | 2019-04-08 | 1 | Accident |
2015-11-26 | 2015-11-27 | 1 | Natural |
point_size <- 3
jitter_amount <- 25
ggplot(data, aes(x = as.Date(Date_Death), y = as.Date(PrisonReleaseDate), color = Days_Between, shape = Manner_Death)) +
geom_point(size = point_size, position = position_jitter(width = jitter_amount, height = jitter_amount)) +
scale_color_gradient(low = "blue", high = "red", name = "Difference Dates, days") +
labs(x = "Date of Death", y = "Date of Prison Release", title = "Relationship between Date_Death and PrisonReleaseDate, observed FDOC Deaths") +
theme_minimal()
Zooming in to the interesting part!
point_size <- 3
x_jitter_amount <- 1450
y_jitter_amount <- 20
ggplot(data, aes(x = as.Date(Date_Death), y = as.Date(PrisonReleaseDate), color = Days_Between, shape = Manner_Death)) +
geom_point(size = point_size, position = position_jitterdodge(jitter.width = x_jitter_amount, jitter.height = y_jitter_amount)) +
scale_color_gradient(low = "blue", high = "red", name = "Difference Dates, days") +
labs(x = "DateDeath", y = "Date of PrisonReleaseDate", title = "Relationship between Date_Death and PrisonReleaseDate, observed FDOC Deaths") +
scale_y_date(date_labels = "%Y", date_breaks = "6 months") + # Include year on y-axis labels
theme_minimal() +
coord_cartesian(xlim = as.Date(c("2016-06-01", "2017-12-31")), ylim = as.Date(c("2020-06-01", "2020-12-31")))
What you see here is the same plot as above, but zoomed in on the red cluster. The points representing manners of death have been slightly separated to improve visibility.
Explaining what it represents is more challenging and depends on how the FDOC uses PrisonReleaseDate for coding. My assumption is that it is a date that signifies when a person is legally ‘released’ in a specific way with a defined legal meaning.
Based on the data, it appears that the FDOC intentionally delayed processing these death records. This delay is evident as the difference in dates for these observations is much larger compared to others (which have a difference of less than 90 days). Then, the FDOC processed their entire backlog in a single day, right in the midst of the pandemic.
It seems that the processing of these individuals’ paperwork was held for 3.5 years, presumably for a valid reason.
filtered_data <- data %>% filter(Days_Between > 90)
p <- ggplot(filtered_data, aes(x = PrisonReleaseDate)) +
geom_histogram(fill = "blue", color = "black", bins = 30) +
labs(
title = "PrisonReleaseDate for those 'released' more than 90 days after Date_Death",
x = "Prison Release Date",
y = "Frequency"
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
# Calculate the count of observations on a specific date
count_date <- filtered_data %>%
group_by(PrisonReleaseDate) %>%
summarise(count = n())
annotation_date <- as.Date("2020-09-30")
count_for_annotation <- count_date %>%
filter(PrisonReleaseDate == annotation_date) %>%
pull(count)
p +
annotate("text", x = annotation_date-910, y = 198, label = paste("September 30, 2020:", count_for_annotation, "PrisonReleaseDate deaths"), vjust = 1.5)
My point is that I need more data.