Montefiore Medical Center/ Albert Einstein College of Medicine
Linking Census Tracts to United Catchment Areas
This section performs spatial joins between census tracts and the united (merged) transplant center buffers.
Unlike the earlier version—where tracts were joined to individual center buffers—this approach joins tracts to a single merged catchment polygon for each organ, distance, and year.
This prevents duplication and ensures accurate population totals.
Each object contains tract-level population and HIV case estimates for tracts located within the total geographic service area of that center category.
Why This Step Matters
This unified join enables accurate calculation of:
Total population within reach of transplant services
Total number of people living with HIV within those catchment areas
Changes in geographic access across years
Comparisons between Active, HIV R+, and HOPE centers
By eliminating overlap-driven duplication, this approach ensures that access estimates reflect true geographic coverage, not inflated counts.
Click to show/hide R Code
#Join tracts to united bufferstracts_in_buffers_active_united<-list()tracts_in_buffers_HIV_united<-list()tracts_in_buffers_HOPE_united<-list()for (organ_loop in organ_list){for (distance_loop in distance_list){for (year_loop in year_list){message(paste("Currently on:", organ_loop, "", distance_loop, "for year:", year_loop))message("Calculating tracts for active...")#ST join to individual tracts and the united transplant center geography to avoid duplication tracts_in_buffers_active_united[[organ_loop]][[distance_loop]][[year_loop]] <-st_join(Merged_tracts[[year_loop]], Transplant_centers_active_buffer_united[[organ_loop]][[distance_loop]][[year_loop]], join = st_intersects)message("Calculating tracts for HIV...") tracts_in_buffers_HIV_united[[organ_loop]][[distance_loop]][[year_loop]] <-st_join(Merged_tracts[[year_loop]], Transplant_centers_HIV_buffer_united[[organ_loop]][[distance_loop]][[year_loop]], join = st_intersects)message("Calculating tracts for HOPE...") tracts_in_buffers_HOPE_united[[organ_loop]][[distance_loop]][[year_loop]] <-st_join(Merged_tracts[[year_loop]], Transplant_centers_HOPE_buffer_united[[organ_loop]][[distance_loop]][[year_loop]], join = st_intersects) }}}
Other portions of the analysis
Setup: Defines global paths, data sources, cohort inclusion criteria, and analysis-wide constants.
Functions: Reusable helper functions for cohort construction, matching, costing, and modeling.
Tables: Summary tables and regression outputs generated from the final models.
Figures:Visualizations of costs, risks, and model-based estimates.
---title: "Join tracts to united buffers"format: html---## Linking Census Tracts to **United** Catchment AreasThis section performs spatial joins between census tracts and the **united (merged) transplant center buffers**.Unlike the earlier version—where tracts were joined to individual center buffers—this approach joins tracts to a **single merged catchment polygon** for each organ, distance, and year.This prevents duplication and ensures accurate population totals.::: {.Rcode title="Source code"}The full R script is available at:- [`R/join_tracts_to_united_buffers.R`](https://github.com/VagishHemmige/HOPE-CDC-analysis-2026/blob/master/R/join_tracts_to_united_buffers.R)This R script file is itself reliant on the following helper files:- [`R/setup.R`](https://github.com/VagishHemmige/HOPE-CDC-analysis-2026/blob/master/R/setup.R)- [`R/functions.R`](https://github.com/VagishHemmige/HOPE-CDC-analysis-2026/blob/master/R/functions.R):::## Why Use United Buffers?When joining tracts to individual center buffers:- A tract can intersect multiple centers- That tract would appear multiple times- Population totals would be inflated unless deduplicated laterBy first uniting buffers using `st_union()` and then joining:- Each tract appears **at most once**- Population counts reflect total geographic coverage- Overlapping service areas are handled correctlyThis is essential for valid total-access calculations.---## Objects CreatedThree nested list objects are generated:- `tracts_in_buffers_active_united`- `tracts_in_buffers_HIV_united`- `tracts_in_buffers_HOPE_united`Each object is indexed by:1. Organ 2. Distance 3. Year ---## What the Spatial Join DoesFor each:- Organ - Distance - Year The script performs:`st_join(..., join = st_intersects)`This means:> A census tract is included if it intersects the **combined catchment area** of that transplant center group.Because the buffer has already been united:- Each tract can match only once per category- No duplication occurs due to overlapping center service areas---## Resulting StructureAfter the loops complete:- `tracts_in_buffers_active_united[[organ]][[distance]][[year]]`- `tracts_in_buffers_HIV_united[[organ]][[distance]][[year]]`- `tracts_in_buffers_HOPE_united[[organ]][[distance]][[year]]`Each object contains tract-level population and HIV case estimates for tracts located within the total geographic service area of that center category.---## Why This Step MattersThis unified join enables accurate calculation of:- Total population within reach of transplant services - Total number of people living with HIV within those catchment areas - Changes in geographic access across years - Comparisons between Active, HIV R+, and HOPE centers By eliminating overlap-driven duplication, this approach ensures that access estimates reflect **true geographic coverage**, not inflated counts.---```{r, eval=FALSE}#Join tracts to united bufferstracts_in_buffers_active_united<-list()tracts_in_buffers_HIV_united<-list()tracts_in_buffers_HOPE_united<-list()for (organ_loop in organ_list){ for (distance_loop in distance_list){ for (year_loop in year_list){ message(paste("Currently on:", organ_loop, "", distance_loop, "for year:", year_loop)) message("Calculating tracts for active...") #ST join to individual tracts and the united transplant center geography to avoid duplication tracts_in_buffers_active_united[[organ_loop]][[distance_loop]][[year_loop]] <- st_join(Merged_tracts[[year_loop]], Transplant_centers_active_buffer_united[[organ_loop]][[distance_loop]][[year_loop]], join = st_intersects) message("Calculating tracts for HIV...") tracts_in_buffers_HIV_united[[organ_loop]][[distance_loop]][[year_loop]] <- st_join(Merged_tracts[[year_loop]], Transplant_centers_HIV_buffer_united[[organ_loop]][[distance_loop]][[year_loop]], join = st_intersects) message("Calculating tracts for HOPE...") tracts_in_buffers_HOPE_united[[organ_loop]][[distance_loop]][[year_loop]] <- st_join(Merged_tracts[[year_loop]], Transplant_centers_HOPE_buffer_united[[organ_loop]][[distance_loop]][[year_loop]], join = st_intersects) }}}```## Other portions of the analysis- [**Setup**](setup.qmd): Defines global paths, data sources, cohort inclusion criteria, and analysis-wide constants.- [**Functions**](functions.qmd): Reusable helper functions for cohort construction, matching, costing, and modeling.- [**Tables**](tables.qmd): Summary tables and regression outputs generated from the final models.- [**Figures**](figures.qmd):Visualizations of costs, risks, and model-based estimates.- [**About**](about.qmd): methods, assumptions, and disclosures