This is my first blog post on my new website and my first time working with R Markdown as well! Today, I’ll be visualizing homelessness data that I downloaded from HUD. It’s for a (very preliminary) project that I’m working on with my colleague, Francisco Beltran Silva, also at CSUN. I’m not an expert on homelessness and I’m only starting to dip my toe into these waters. Come join me as I learn more about this important issue!
Data Sources
HUD maintains data on homelessness provided to them by CoCs (Continuums of Care). A CoC is a regional or local planning body that coordinates housing services funding for homeless families and individuals. There are two main measures tracked: the housing inventory count (HIC) and the point-in-time count (PIT). HIC measures the number of beds dedicated to the homeless in the CoC. PIT measures the number of people experiencing homelessness in the CoC on a single night in January.
HIC and PIT data by CoC are available from HUD at: https://www.hudexchange.info/resource/3031/pit-and-hic-data-since-2007/.
Shapefiles for each CoC are available at: https://www.hudexchange.info/programs/coc/gis-tools/.
For years prior to 2012, the shapefiles are a bit of a pain to download since a separate file is provided for each state and year. I used the following Python script to download them:
Code
from download import download state_list = ['AL','AK','AZ','AR','CA','CO','CT','DE','DC','FL','GA','GU','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','PR','RI','SC','SD','TN','TX','UT','VT','VI','VA','WA','WV','WI','WY'] year_list = ['2012','2011','2010','2009','2008','2007'] data_dir = 'data' for year in year_list: for state in state_list: filename = f'CoC_GIS_State_Shapefile_{state}_{year}.zip' url = f'https://files.hudexchange.info/reports/published/{filename}' download_path = f'{data_dir}/{filename}' download(url, download_path, progressbar=True)
I processed the raw files to obtain PIT and HIC counts by CoC-Year from 2007 to 2020. It was a pain to work with, but you can download the files I used here and here.
Homelessness Since 2007
Let’s get to visualizing! First, let’s plot national PIT and HIC count for each year since 2007.
Code
library(ggplot2) library(ggthemes) library(ggrepel) library(scales) library(tidyverse) library(knitr) library(kableExtra) PIT.by.CoC.Year <- read.csv("PIT_by_CoC_Year.csv") PIT.by.Year <- PIT.by.CoC.Year %>% group_by(Year) %>% summarize( Homeless = sum(Homeless, na.rm=T), Sheltered.Homeless = sum(Sheltered.Homeless, na.rm=T), Unsheltered.Homeless = sum(Unsheltered.Homeless, na.rm=T), Chronic.Homeless = sum(Chronic.Homeless, na.rm=T), Sheltered.Chronic.Homeless = sum(Sheltered.Chronic.Homeless, na.rm=T), Unsheltered.Chronic.Homeless = sum(Unsheltered.Chronic.Homeless, na.rm=T), ) ggplot(data=PIT.by.Year) + geom_line(aes(x=Year, y=Homeless), size=1) + geom_point(aes(x=Year, y=Homeless), shape=21, fill="white", size=4) + geom_text(aes(x=Year, y=Homeless, label=format(Homeless,big.mark=",")), angle=45, hjust=-0.2, vjust=-0.2) + scale_y_continuous( limits=c(0,800000), labels=function(x) format(x,big.mark=",",scientific=F)) + coord_cartesian(clip="off") + ggtitle("Overall Homelessness in America, 2007-2020") + theme_bw() + theme(plot.margin=unit(c(6,20,6,6),"pt"))
Homelessness declined from 650,000 in 2007 to 580,000 in 2020. However, the number of homeless has been increasing since 2016.
Sheltered and Unsheltered
Let’s explore the composition of the change between the unsheltered and the sheltered.
Code
PIT.by.Year$Sheltered.Homeless.Chg <- PIT.by.Year$Sheltered.Homeless - PIT.by.Year$Sheltered.Homeless[1] PIT.by.Year$Unsheltered.Homeless.Chg <- PIT.by.Year$Unsheltered.Homeless - PIT.by.Year$Unsheltered.Homeless[1] PIT.by.Year[9,"lab1"] <- "Sheltered" PIT.by.Year[7,"lab2"] <- "Unsheltered" ggplot(data=PIT.by.Year) + geom_line(aes(x=Year,y=Sheltered.Homeless.Chg), size=1, color=hue_pal()(2)[1]) + geom_point(aes(x=Year,y=Sheltered.Homeless.Chg), size=4, color=hue_pal()(2)[1]) + geom_text(aes(x=Year,y=Sheltered.Homeless.Chg, label=lab1), hjust=-0.18, vjust=-0.1, color=hue_pal()(2)[1]) + geom_line(aes(x=Year,y=Unsheltered.Homeless.Chg), size=1, color=hue_pal()(2)[2]) + geom_point(aes(x=Year,y=Unsheltered.Homeless.Chg), size=4, color=hue_pal()(2)[2]) + geom_text(aes(x=Year,y=Unsheltered.Homeless.Chg, label=lab2), hjust=1.15, vjust=1, color=hue_pal()(2)[2]) + scale_y_continuous( labels=function(x) format(x,big.mark=",",scientific=F)) + ggtitle("Change in Homelessness Since 2007: Sheltered and Unsheltered") + ylab("Difference Since 2007") + coord_cartesian(clip="off") + theme_bw()
There’s been a net decline of about 30,000 for both the sheltered and the unsheltered homeless from 2007 to 2020. However, this masks substantial heterogeneity in recent and past time trends. The decline in homelessness from 2007 to 2015 was almost entirely driven by a decline in the unsheltered homeless. It seems there was some policy success in sheltering the homeless from 2007 to 2015. From 2015 to 2020, there has been an increase of 50,000 in the unsheltered homeless. Much of this increase appears to be drawn from the sheltered homeless population. Something happened in 2015 to increase the rate of unsheltered homelessness.
Chronically Homeless
Now let’s take a look at the chronically homeless. HUD defines a chronically homeless person as someone who has been homeless continuously for 12 months or has had at least 4 separate occasions of homelessness in the past 3 years.
Code
PIT.by.Year$Chronic.Homeless.Chg <- PIT.by.Year$Chronic.Homeless - PIT.by.Year$Chronic.Homeless[1] PIT.by.Year$Unchronic.Homeless.Chg <- PIT.by.Year$Homeless - PIT.by.Year$Homeless[1] - PIT.by.Year$Chronic.Homeless.Chg PIT.by.Year[6,"lab3"] <- "Chronically Homeless" PIT.by.Year[8,"lab4"] <- "Not Chronically Homeless" ggplot(data=PIT.by.Year) + geom_line(aes(x=Year,y=Chronic.Homeless.Chg), size=1, color=hue_pal()(2)[1]) + geom_point(aes(x=Year,y=Chronic.Homeless.Chg), size=4, color=hue_pal()(2)[1]) + geom_text(aes(x=Year,y=Chronic.Homeless.Chg, label=lab3), hjust=-0.1, vjust=-0.1, color=hue_pal()(2)[1]) + geom_line(aes(x=Year,y=Unchronic.Homeless.Chg), size=1, color=hue_pal()(2)[2]) + geom_point(aes(x=Year,y=Unchronic.Homeless.Chg), size=4, color=hue_pal()(2)[2]) + geom_text(aes(x=Year,y=Unchronic.Homeless.Chg, label=lab4), hjust=1.1, vjust=1, color=hue_pal()(2)[2]) + scale_y_continuous( labels=function(x) format(x,big.mark=",",scientific=F)) + ggtitle("Change in Homelessness Since 2007: Chronic and Not Chronic") + ylab("Difference Since 2007") + coord_cartesian(clip="off") + theme_bw()
The net decline in homelessness since 2007 appears entirely driven by a decline in temporary homelessness. The increase in homelessness since 2016 appears entirely driven by an increase in the chronically homeless.
Change in Homelessness by State
Next let’s take a look at how homelessness has been changing by state.
Code
PIT.by.CoC.Year$State <- substr(PIT.by.CoC.Year$CoC.Id,1,2) PIT.by.State.Year <- PIT.by.CoC.Year %>% group_by(State, Year) %>% summarize( Homeless = sum(Homeless, na.rm=T), Sheltered.Homeless = sum(Sheltered.Homeless, na.rm=T), Unsheltered.Homeless = sum(Unsheltered.Homeless, na.rm=T), Chronic.Homeless = sum(Chronic.Homeless, na.rm=T), Sheltered.Chronic.Homeless = sum(Sheltered.Chronic.Homeless, na.rm=T), Unsheltered.Chronic.Homeless = sum(Unsheltered.Chronic.Homeless, na.rm=T) ) PIT.by.State.Year.Wide <- PIT.by.State.Year %>% pivot_wider( names_from = Year, values_from = c("Homeless","Sheltered.Homeless","Unsheltered.Homeless", "Chronic.Homeless","Sheltered.Chronic.Homeless", "Unsheltered.Chronic.Homeless") ) PIT.by.State.Year.Wide <- PIT.by.State.Year.Wide %>% mutate( Homeless.Chg.2007.2020 = Homeless_2020 - Homeless_2007, Homeless.Chg.2007.2015 = Homeless_2015 - Homeless_2007, Homeless.Chg.2015.2020 = Homeless_2020 - Homeless_2015, Unsheltered.Homeless.Chg.2007.2020 = Unsheltered.Homeless_2020 - Unsheltered.Homeless_2007, Unsheltered.Homeless.Chg.2007.2015 = Unsheltered.Homeless_2015 - Unsheltered.Homeless_2007, Unsheltered.Homeless.Chg.2015.2020 = Unsheltered.Homeless_2020 - Unsheltered.Homeless_2015, Chronic.Homeless.Chg.2007.2020 = Chronic.Homeless_2020 - Chronic.Homeless_2007, Chronic.Homeless.Chg.2007.2015 = Chronic.Homeless_2015 - Chronic.Homeless_2007, Chronic.Homeless.Chg.2015.2020 = Chronic.Homeless_2020 - Chronic.Homeless_2015, ) %>% subset(!(State %in% c("GU","PR","MP","VI"))) mytable <- select(PIT.by.State.Year.Wide, State, Homeless.Chg.2007.2020, Homeless.Chg.2007.2015, Homeless.Chg.2015.2020, Unsheltered.Homeless.Chg.2007.2020, Unsheltered.Homeless.Chg.2007.2015, Unsheltered.Homeless.Chg.2015.2020, Chronic.Homeless.Chg.2007.2020, Chronic.Homeless.Chg.2007.2015, Chronic.Homeless.Chg.2015.2020) kable( mytable %>% arrange(desc(Homeless.Chg.2007.2020)), caption = "<strong>Change in Homelessness by State</strong>", format = "html", format.args = list(big.mark=","), col.names = c("State","2007-2020","2007-2015","2015-2020","2007-2020","2007-2015","2015-2020","2007-2020","2007-2015","2015-2020") ) %>% kable_styling("striped") %>% add_header_above(c(" " = 1, "Overall Homeless" = 3, "Unsheltered Homeless" = 3, "Chronic Homeless" = 3))
State | 2007-2020 | 2007-2015 | 2015-2020 | 2007-2020 | 2007-2015 | 2015-2020 | 2007-2020 | 2007-2015 | 2015-2020 |
---|---|---|---|---|---|---|---|---|---|
NY | 28,670 | 25,649 | 3,021 | -763 | -1,298 | 535 | 1,039 | 640 | 399 |
CA | 22,562 | -23,248 | 45,810 | 23,185 | -16,776 | 39,961 | 11,444 | -8,114 | 19,558 |
MA | 2,848 | 6,008 | -3,160 | -120 | -821 | 701 | -748 | -229 | -519 |
DC | 1,060 | 1,978 | -918 | 313 | 204 | 109 | -308 | 30 | -338 |
MN | 617 | 223 | 394 | 504 | -604 | 1,108 | 373 | -18 | 391 |
ID | 566 | 217 | 349 | 419 | -155 | 574 | 269 | 150 | 119 |
SD | 479 | 457 | 22 | 205 | 95 | 110 | 58 | -9 | 67 |
MT | 395 | 559 | -164 | 165 | 577 | -412 | 140 | 83 | 57 |
HI | 388 | 1,550 | -1,162 | 292 | 485 | -193 | 900 | 756 | 144 |
MO | 333 | 288 | 45 | 563 | -61 | 624 | -113 | -174 | 61 |
NM | 318 | -386 | 704 | -8 | -813 | 805 | 823 | 5 | 818 |
AK | 307 | 314 | -7 | -31 | 62 | -93 | 79 | -56 | 135 |
KS | 285 | 424 | -139 | 175 | 45 | 130 | 203 | 198 | 5 |
UT | 120 | 14 | 106 | 391 | -87 | 478 | -113 | -568 | 455 |
DE | 104 | -108 | 212 | -57 | -170 | 113 | 117 | -70 | 187 |
VT | 75 | 488 | -413 | -201 | -165 | -36 | -6 | -25 | 19 |
WY | 75 | 261 | -186 | -17 | 151 | -168 | 43 | 64 | -21 |
IA | -87 | 347 | -434 | 40 | -90 | 130 | 61 | -32 | 93 |
ND | -95 | 669 | -764 | -25 | 427 | -452 | 12 | 58 | -46 |
RI | -268 | -261 | -7 | 59 | -13 | 72 | 92 | -4 | 96 |
MS | -270 | 606 | -876 | 0 | 316 | -316 | -447 | -350 | -97 |
OK | -289 | -444 | 155 | 112 | -354 | 466 | 349 | -198 | 547 |
WA | -456 | -3,960 | 3,504 | 4,292 | 599 | 3,693 | 4,153 | -121 | 4,274 |
ME | -541 | -266 | -275 | 79 | -3 | 82 | 151 | 120 | 31 |
NH | -573 | -803 | 230 | -627 | -843 | 216 | 79 | -50 | 129 |
OH | -609 | -82 | -527 | -40 | -785 | 745 | -1,555 | -1,033 | -522 |
WV | -1,068 | -574 | -494 | 15 | 170 | -155 | -977 | -765 | -212 |
NE | -1,127 | -787 | -340 | -381 | -401 | 20 | -322 | -463 | 141 |
WI | -1,133 | 409 | -1,542 | -239 | -121 | -118 | -78 | -225 | 147 |
SC | -1,373 | -306 | -1,067 | -870 | -678 | -192 | 291 | 447 | -156 |
AR | -1,470 | -1,276 | -194 | -278 | -669 | 391 | -338 | -229 | -109 |
CT | -1,577 | -435 | -1,142 | -486 | -185 | -301 | -846 | -440 | -406 |
IN | -1,733 | -1,495 | -238 | -296 | -679 | 383 | -291 | 9 | -300 |
NV | -1,742 | 101 | -1,843 | 385 | 391 | -6 | 498 | -277 | 775 |
AL | -2,101 | -1,482 | -619 | -357 | -629 | 272 | -490 | -386 | -104 |
LA | -2,321 | -1,413 | -908 | -424 | -386 | -38 | -125 | 211 | -336 |
NC | -2,522 | -1,117 | -1,405 | -1,365 | -1,498 | 133 | -373 | -281 | -92 |
PA | -2,845 | -799 | -2,046 | 378 | -51 | 429 | 183 | 1 | 182 |
OR | -2,935 | -4,364 | 1,429 | -384 | -1,866 | 1,482 | 1,510 | 1,182 | 328 |
MD | -3,268 | -1,238 | -2,030 | -1,974 | -1,414 | -560 | -153 | 297 | -450 |
AZ | -3,667 | -4,750 | 1,083 | -507 | -3,071 | 2,564 | -718 | -1,438 | 720 |
VA | -3,789 | -2,745 | -1,044 | -1,211 | -1,368 | 157 | -1,150 | -805 | -345 |
TN | -3,954 | -2,087 | -1,867 | -1,980 | -1,520 | -460 | -1,614 | -1,117 | -497 |
KY | -4,050 | -3,523 | -527 | -1,193 | -1,379 | 186 | 92 | -117 | 209 |
CO | -4,379 | -4,272 | -107 | -4,341 | -4,435 | 94 | 904 | -173 | 1,077 |
IL | -5,056 | -2,310 | -2,746 | -1,038 | -602 | -436 | -376 | -769 | 393 |
NJ | -7,652 | -7,216 | -436 | -697 | -1,504 | 807 | -782 | -1,115 | 333 |
GA | -9,405 | -5,849 | -3,556 | -7,142 | -5,495 | -1,647 | -1,110 | -347 | -763 |
TX | -12,559 | -16,110 | 3,551 | -3,694 | -9,420 | 5,726 | -3,898 | -3,627 | -271 |
MI | -19,657 | -17,779 | -1,878 | -15,704 | -15,671 | -33 | -1,607 | -1,781 | 174 |
FL | -20,582 | -12,169 | -8,413 | -14,868 | -10,523 | -4,345 | -2,281 | -923 | -1,358 |
Although homelessness declined in the country from 2007 to 2020, it increased in California and New York over the same period. Curiously, the rise in homelessness in California and New York happened in different periods. New York experienced the largest increase in homelessness from 2007 to 2015. California, on the other hand, saw a large decline in homelessness from 2007 to 2015, but that decline was wiped out by the enormous increase from 2015 to 2020. California accounts for more than 100% of the nationwide increase in homelessness from 2015 to 2020.
Conclusion
This exercise has revealed some interesting facts.
First, it appears that there are two different trends driving homeless patterns from 2007 to 2020. The first is a broad-based decline in homelessness from 2007 to 2015, driven primarily by a decline in the unsheltered homeless. The second is an increase in homelessness from 2015 to 2020, driven primarily by an increase in the unsheltered homeless and the chronically homeless. The increase appears to be driven almost entirely by California.
Second, it appears that the recent uptick in homelessness is almost entirely a California phenomenon. Curiously, California was doing well in decreasing its number of homeless from 2007 to 2015. So what changed in 2015? It seems like any attempt to understand recent Californian homelessness needs to be aware of these facts.