This healthcare equity analysis explores the spatial distribution of hospitals in Fulton and Dekalb counties through the lenses of poverty, health insurance, and individuals with disability.
# Load required packages
library(sf)
library(dplyr)
library(tidycensus)
library(tmap)
library(jsonlite)
library(tidyverse)
library(httr)
library(reshape2)
library(here)
library(knitr)
library(skimr)
library(units)
library(tidyr)
library(purrr)
# Read the Yelp hospital data
yelp_hospital <- st_read("https://raw.githubusercontent.com/ujhwang/urban-analytics-2024/main/Assignment/mini_3/yelp_hospital.geojson")
## Reading layer `yelp_hospital' from data source
## `https://raw.githubusercontent.com/ujhwang/urban-analytics-2024/main/Assignment/mini_3/yelp_hospital.geojson'
## using driver `GeoJSON'
## Simple feature collection with 129 features and 23 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -84.56242 ymin: 33.60009 xmax: -84.08677 ymax: 34.0701
## Geodetic CRS: WGS 84
# Check for duplicates
sum(duplicated(yelp_hospital))
## [1] 0
# Check the class of each column
column_classes <- sapply(yelp_hospital, class)
print(column_classes)
## $id
## [1] "character"
##
## $alias
## [1] "character"
##
## $name
## [1] "character"
##
## $image_url
## [1] "character"
##
## $is_closed
## [1] "logical"
##
## $url
## [1] "character"
##
## $review_count
## [1] "integer"
##
## $categories
## [1] "character"
##
## $rating
## [1] "numeric"
##
## $transactions
## [1] "character"
##
## $phone
## [1] "character"
##
## $display_phone
## [1] "character"
##
## $distance
## [1] "numeric"
##
## $coordinates.latitude
## [1] "numeric"
##
## $coordinates.longitude
## [1] "numeric"
##
## $location.address1
## [1] "character"
##
## $location.address2
## [1] "character"
##
## $location.address3
## [1] "character"
##
## $location.city
## [1] "character"
##
## $location.zip_code
## [1] "character"
##
## $location.country
## [1] "character"
##
## $location.state
## [1] "character"
##
## $location.display_address
## [1] "character"
##
## $geometry
## [1] "sfc_POINT" "sfc"
# View the structure of the dataset
str(yelp_hospital)
## Classes 'sf' and 'data.frame': 129 obs. of 24 variables:
## $ id : chr "fiSgDb29cZO-MffxwrT_LA" "hWXJFx9zCVDmiO6eldgHBA" "kuE7B_HLP57KnSIgn-jzpw" "0B80Az6DXX8ZLXZXhU1bCQ" ...
## $ alias : chr "northside-alpharetta-medical-campus-alpharetta-2" "regency-hospital-alpharetta" "northside-alpharetta-preventive-medicine-atlanta" "health-direct-alpharetta" ...
## $ name : chr "Northside Alpharetta Medical Campus" "Regency Hospital" "Northside Alpharetta Preventive Medicine" "Health Direct" ...
## $ image_url : chr "https://s3-media4.fl.yelpcdn.com/bphoto/8Pe7ZlobOywD_CakTalTdg/o.jpg" "" "" "" ...
## $ is_closed : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ url : chr "https://www.yelp.com/biz/northside-alpharetta-medical-campus-alpharetta-2?adjust_creative=kfv-AqbqsBxwk_npQxknW"| __truncated__ "https://www.yelp.com/biz/regency-hospital-alpharetta?adjust_creative=kfv-AqbqsBxwk_npQxknWQ&utm_campaign=yelp_a"| __truncated__ "https://www.yelp.com/biz/northside-alpharetta-preventive-medicine-atlanta?adjust_creative=kfv-AqbqsBxwk_npQxknW"| __truncated__ "https://www.yelp.com/biz/health-direct-alpharetta?adjust_creative=kfv-AqbqsBxwk_npQxknWQ&utm_campaign=yelp_api_"| __truncated__ ...
## $ review_count : int 1 0 0 0 0 34 0 0 0 0 ...
## $ categories : chr "Hospitals" "Hospitals" "Hospitals" "Hospitals" ...
## $ rating : num 4 0 0 0 0 3.2 0 0 0 0 ...
## $ transactions : chr "" "" "" "" ...
## $ phone : chr "+17706674000" "+16786940553" "+17706674155" "+17708702500" ...
## $ display_phone : chr "(770) 667-4000" "(678) 694-0553" "(770) 667-4155" "(770) 870-2500" ...
## $ distance : num 1497 2126 1497 2460 595 ...
## $ coordinates.latitude : num 34.1 34.1 34.1 34.1 33.8 ...
## $ coordinates.longitude : num -84.3 -84.3 -84.3 -84.3 -84.4 ...
## $ location.address1 : chr "3400 A & C Old Milton Pkwy" "11175 Cicero Dr" "3400 A Old Milton Pkwy" "2550 Northwinds Pkwy" ...
## $ location.address2 : chr "" "Ste 300" "" "" ...
## $ location.address3 : chr "" NA "" "" ...
## $ location.city : chr "Alpharetta" "Alpharetta" "Atlanta" "Alpharetta" ...
## $ location.zip_code : chr "30004" "30022" "30303" "30004" ...
## $ location.country : chr "US" "US" "US" "US" ...
## $ location.state : chr "GA" "GA" "GA" "GA" ...
## $ location.display_address: chr "3400 A & C Old Milton Pkwy, Alpharetta, GA 30004" "11175 Cicero Dr, Ste 300, Alpharetta, GA 30022" "3400 A Old Milton Pkwy, Atlanta, GA 30303" "2550 Northwinds Pkwy, Alpharetta, GA 30004" ...
## $ geometry :sfc_POINT of length 129; first list element: 'XY' num -84.3 34.1
## - attr(*, "sf_column")= chr "geometry"
## - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA NA NA NA ...
## ..- attr(*, "names")= chr [1:23] "id" "alias" "name" "image_url" ...
# Check for list columns
list_columns <- sapply(yelp_hospital, is.list)
print(list_columns)
## id alias name
## FALSE FALSE FALSE
## image_url is_closed url
## FALSE FALSE FALSE
## review_count categories rating
## FALSE FALSE FALSE
## transactions phone display_phone
## FALSE FALSE FALSE
## distance coordinates.latitude coordinates.longitude
## FALSE FALSE FALSE
## location.address1 location.address2 location.address3
## FALSE FALSE FALSE
## location.city location.zip_code location.country
## FALSE FALSE FALSE
## location.state location.display_address geometry
## FALSE FALSE TRUE
# Flatten nested columns and handle nested structures
yelp_hospital_flat <- yelp_hospital %>%
jsonlite::flatten() %>%
mutate(
transactions = map_chr(transactions, ~ str_c(., collapse = ", ")),
location.display_address = map_chr(location.display_address, ~ str_c(., collapse = ", ")),
categories = map_chr(categories, ~ str_c(., collapse = ", "))
)
# Filter to remove rows with missing coordinates from the flattened dataset
yelp_hospital_clean <- yelp_hospital_flat %>%
filter(!is.na(coordinates.latitude) & !is.na(coordinates.longitude))
I selected the following variables for analysis: Total population for whom poverty status is determined, Population without health insurance, and Population with a disability.
Poverty is a key indicator of socioeconomic status and directly affects access to healthcare services, as individuals living in poverty often face barriers such as financial constraints, lack of transportation, and difficulty in accessing nearby healthcare facilities.
Insurance status is also a major determinant of access to healthcare services, as ndividuals without health insurance are less likely to seek timely medical care due to cost concerns.
Finally, people with disabilities often face physical and systemic barriers to healthcare, including transportation challenges, the need for specialized facilities, and difficulties in navigating the healthcare system.
These variables help assess whether hospital distribution is equitably clustered around at-risk populations.
# Set Census API key
tidycensus::census_api_key(Sys.getenv("CENSUS_API_KEY"))
# Download ACS data for Census Tracts in Fulton and DeKalb counties
variables <- c(
total_population = "B01003_001", # Total population of the census tract
population_below_poverty = "B17001_002", # Population below the poverty level
uninsured_total = "B27001_003", # Population without health insurance
population_with_disability = "B18101_002" # Population with a disability
)
# Download the ACS data for Fulton and DeKalb counties
tract_data <- get_acs(
geography = "tract",
state = "GA",
county = c("DeKalb", "Fulton"),
variables = variables,
year = 2021, # Use the latest available year
survey = "acs5",
geometry = TRUE, # Include geometrical data
output = "wide" # Output format
)
## | | | 0% | |= | 1% | |== | 2% | |== | 3% | |==== | 5% | |==== | 6% | |===== | 7% | |====== | 9% | |======== | 11% | |========= | 13% | |========== | 14% | |=========== | 16% | |============ | 17% | |============== | 20% | |=============== | 22% | |================ | 23% | |=================== | 27% | |===================== | 30% | |====================== | 31% | |======================= | 33% | |======================== | 35% | |=========================== | 39% | |=============================== | 45% | |================================ | 46% | |================================= | 48% | |================================== | 49% | |===================================== | 52% | |======================================= | 55% | |======================================== | 57% | |========================================= | 59% | |=========================================== | 62% | |============================================ | 63% | |=============================================== | 67% | |================================================ | 68% | |================================================= | 70% | |=================================================== | 72% | |===================================================== | 76% | |======================================================= | 78% | |======================================================== | 80% | |========================================================= | 82% | |========================================================== | 83% | |=========================================================== | 84% | |============================================================== | 88% | |============================================================== | 89% | |================================================================ | 92% | |================================================================== | 95% | |=================================================================== | 96% | |===================================================================== | 99% | |======================================================================| 100%
# Check for NA values in the dataset
na_summary <- tract_data %>%
summarise(across(everything(), ~ sum(is.na(.)))) # Count NAs in each column
print(na_summary)
## Simple feature collection with 1 feature and 10 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -84.85071 ymin: 33.50251 xmax: -84.02371 ymax: 34.18629
## Geodetic CRS: NAD83
## GEOID NAME total_populationE total_populationM population_below_povertyE
## 1 0 0 0 0 0
## population_below_povertyM uninsured_totalE uninsured_totalM
## 1 0 0 0
## population_with_disabilityE population_with_disabilityM
## 1 0 0
## geometry
## 1 POLYGON ((-84.09722 33.7983...
# Create Variable for Proportion of Uninsured Population
tract_data <- tract_data %>%
mutate(uninsured_proportion = uninsured_totalE / total_populationE)
# Create Variable for Proportion of Total Population in Poverty
tract_data <- tract_data %>%
mutate(poverty_proportion = population_below_povertyE / total_populationE)
# Create Ratio of Population with Disabilities to Total Population
tract_data <- tract_data %>%
mutate(disability_ratio = population_with_disabilityE / total_populationE)
# Check the CRS of the Yelp hospital data
yelp_crs <- st_crs(yelp_hospital_clean)
print(yelp_crs)
## Coordinate Reference System:
## User input: WGS 84
## wkt:
## GEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["geodetic latitude (Lat)",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["geodetic longitude (Lon)",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]]
# Check the CRS of the ACS tract data
tract_crs <- st_crs(tract_data)
print(tract_crs)
## Coordinate Reference System:
## User input: NAD83
## wkt:
## GEOGCRS["NAD83",
## DATUM["North American Datum 1983",
## ELLIPSOID["GRS 1980",6378137,298.257222101,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["latitude",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["longitude",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4269]]
# Transform ACS tract data CRS to WGS 84
if (tract_crs != yelp_crs) {
tract_data <- st_transform(tract_data, st_crs(yelp_hospital_clean))
}
# Join Yelp data with Census Tract data based on spatial location
joined_data <- st_join(yelp_hospital_clean, tract_data)
# View the first few rows of the joined dataset
print(head(joined_data))
## Simple feature collection with 6 features and 36 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -84.39409 ymin: 33.81016 xmax: -84.26324 ymax: 34.0701
## Geodetic CRS: WGS 84
## id alias
## 1 fiSgDb29cZO-MffxwrT_LA northside-alpharetta-medical-campus-alpharetta-2
## 2 hWXJFx9zCVDmiO6eldgHBA regency-hospital-alpharetta
## 3 kuE7B_HLP57KnSIgn-jzpw northside-alpharetta-preventive-medicine-atlanta
## 4 0B80Az6DXX8ZLXZXhU1bCQ health-direct-alpharetta
## 5 EaD2lKlKh4NpeSD25_vrHw ultimatemedicalhousecall-atlanta
## 6 O4DoAVRc6oTjUe9ufieTjA shepherd-center-atlanta
## name
## 1 Northside Alpharetta Medical Campus
## 2 Regency Hospital
## 3 Northside Alpharetta Preventive Medicine
## 4 Health Direct
## 5 Ultimatemedicalhousecall
## 6 Shepherd Center
## image_url
## 1 https://s3-media4.fl.yelpcdn.com/bphoto/8Pe7ZlobOywD_CakTalTdg/o.jpg
## 2
## 3
## 4
## 5
## 6 https://s3-media2.fl.yelpcdn.com/bphoto/7H4uUz1eDFV1a2fM-5-e2A/o.jpg
## is_closed
## 1 FALSE
## 2 FALSE
## 3 FALSE
## 4 FALSE
## 5 FALSE
## 6 FALSE
## url
## 1 https://www.yelp.com/biz/northside-alpharetta-medical-campus-alpharetta-2?adjust_creative=kfv-AqbqsBxwk_npQxknWQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=kfv-AqbqsBxwk_npQxknWQ
## 2 https://www.yelp.com/biz/regency-hospital-alpharetta?adjust_creative=kfv-AqbqsBxwk_npQxknWQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=kfv-AqbqsBxwk_npQxknWQ
## 3 https://www.yelp.com/biz/northside-alpharetta-preventive-medicine-atlanta?adjust_creative=kfv-AqbqsBxwk_npQxknWQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=kfv-AqbqsBxwk_npQxknWQ
## 4 https://www.yelp.com/biz/health-direct-alpharetta?adjust_creative=kfv-AqbqsBxwk_npQxknWQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=kfv-AqbqsBxwk_npQxknWQ
## 5 https://www.yelp.com/biz/ultimatemedicalhousecall-atlanta?adjust_creative=kfv-AqbqsBxwk_npQxknWQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=kfv-AqbqsBxwk_npQxknWQ
## 6 https://www.yelp.com/biz/shepherd-center-atlanta?adjust_creative=kfv-AqbqsBxwk_npQxknWQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=kfv-AqbqsBxwk_npQxknWQ
## review_count categories
## 1 1 Hospitals
## 2 0 Hospitals
## 3 0 Hospitals
## 4 0 Hospitals
## 5 0 Hospitals
## 6 34 Hospitals, Rehabilitation Center, Community Service/Non-Profit
## rating transactions phone display_phone distance
## 1 4.0 +17706674000 (770) 667-4000 1496.5068
## 2 0.0 +16786940553 (678) 694-0553 2125.5366
## 3 0.0 +17706674155 (770) 667-4155 1496.5068
## 4 0.0 +17708702500 (770) 870-2500 2460.2880
## 5 0.0 595.1797
## 6 3.2 +14043522020 (404) 352-2020 769.8365
## coordinates.latitude coordinates.longitude location.address1
## 1 34.07010 -84.26324 3400 A & C Old Milton Pkwy
## 2 34.05106 -84.27857 11175 Cicero Dr
## 3 34.07010 -84.26324 3400 A Old Milton Pkwy
## 4 34.06029 -84.28281 2550 Northwinds Pkwy
## 5 33.84957 -84.37021 3495 Buckhead Lp NE
## 6 33.81016 -84.39409 2020 Peachtree Rd NW
## location.address2 location.address3 location.city location.zip_code
## 1 Alpharetta 30004
## 2 Ste 300 <NA> Alpharetta 30022
## 3 Atlanta 30303
## 4 Alpharetta 30004
## 5 <NA> Atlanta 30305
## 6 Atlanta 30309
## location.country location.state
## 1 US GA
## 2 US GA
## 3 US GA
## 4 US GA
## 5 US GA
## 6 US GA
## location.display_address GEOID
## 1 3400 A & C Old Milton Pkwy, Alpharetta, GA 30004 13121011636
## 2 11175 Cicero Dr, Ste 300, Alpharetta, GA 30022 13121011637
## 3 3400 A Old Milton Pkwy, Atlanta, GA 30303 13121011636
## 4 2550 Northwinds Pkwy, Alpharetta, GA 30004 13121011639
## 5 3495 Buckhead Lp NE, Atlanta, GA 30305 13121010003
## 6 2020 Peachtree Rd NW, Atlanta, GA 30309 13121009104
## NAME total_populationE
## 1 Census Tract 116.36, Fulton County, Georgia 1827
## 2 Census Tract 116.37, Fulton County, Georgia 2428
## 3 Census Tract 116.36, Fulton County, Georgia 1827
## 4 Census Tract 116.39, Fulton County, Georgia 1965
## 5 Census Tract 100.03, Fulton County, Georgia 3482
## 6 Census Tract 91.04, Fulton County, Georgia 2657
## total_populationM population_below_povertyE population_below_povertyM
## 1 432 18 31
## 2 315 0 14
## 3 432 18 31
## 4 550 99 90
## 5 686 398 212
## 6 401 290 208
## uninsured_totalE uninsured_totalM population_with_disabilityE
## 1 0 14 995
## 2 44 53 1186
## 3 0 14 995
## 4 149 167 874
## 5 56 54 1820
## 6 29 51 1048
## population_with_disabilityM uninsured_proportion poverty_proportion
## 1 279 0.00000000 0.009852217
## 2 207 0.01812191 0.000000000
## 3 279 0.00000000 0.009852217
## 4 284 0.07582697 0.050381679
## 5 470 0.01608271 0.114302125
## 6 263 0.01091457 0.109145653
## disability_ratio geometry
## 1 0.5446086 POINT (-84.26324 34.0701)
## 2 0.4884679 POINT (-84.27857 34.05106)
## 3 0.5446086 POINT (-84.26324 34.0701)
## 4 0.4447837 POINT (-84.28281 34.06029)
## 5 0.5226881 POINT (-84.37021 33.84957)
## 6 0.3944298 POINT (-84.39409 33.81016)
# Summary of the joined data
summary(joined_data)
## id alias name image_url
## Length:129 Length:129 Length:129 Length:129
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## is_closed url review_count categories
## Mode :logical Length:129 Min. : 0.0 Length:129
## FALSE:129 Class :character 1st Qu.: 0.0 Class :character
## Mode :character Median : 0.0 Mode :character
## Mean : 12.9
## 3rd Qu.: 2.0
## Max. :319.0
## rating transactions phone display_phone
## Min. :0.000 Length:129 Length:129 Length:129
## 1st Qu.:0.000 Class :character Class :character Class :character
## Median :0.000 Mode :character Mode :character Mode :character
## Mean :1.054
## 3rd Qu.:2.000
## Max. :5.000
## distance coordinates.latitude coordinates.longitude location.address1
## Min. : 204.1 Min. :33.60 Min. :-84.56 Length:129
## 1st Qu.: 564.8 1st Qu.:33.77 1st Qu.:-84.39 Class :character
## Median :1199.7 Median :33.81 Median :-84.35 Mode :character
## Mean :1188.1 Mean :33.86 Mean :-84.34
## 3rd Qu.:1647.7 3rd Qu.:33.92 3rd Qu.:-84.32
## Max. :4098.4 Max. :34.07 Max. :-84.09
## location.address2 location.address3 location.city location.zip_code
## Length:129 Length:129 Length:129 Length:129
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## location.country location.state location.display_address
## Length:129 Length:129 Length:129
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
## GEOID NAME total_populationE total_populationM
## Length:129 Length:129 Min. :1635 Min. : 254.0
## Class :character Class :character 1st Qu.:2103 1st Qu.: 450.0
## Mode :character Mode :character Median :2897 Median : 599.0
## Mean :3229 Mean : 602.3
## 3rd Qu.:4212 3rd Qu.: 676.0
## Max. :6542 Max. :2352.0
## population_below_povertyE population_below_povertyM uninsured_totalE
## Min. : 0.0 Min. : 14.0 Min. : 0.00
## 1st Qu.: 155.0 1st Qu.:104.0 1st Qu.: 44.00
## Median : 287.0 Median :188.0 Median : 64.00
## Mean : 341.2 Mean :199.7 Mean : 91.15
## 3rd Qu.: 447.0 3rd Qu.:258.0 3rd Qu.:120.00
## Max. :1251.0 Max. :670.0 Max. :348.00
## uninsured_totalM population_with_disabilityE population_with_disabilityM
## Min. : 14.0 Min. : 507 Min. : 161
## 1st Qu.: 38.0 1st Qu.:1023 1st Qu.: 295
## Median : 66.0 Median :1404 Median : 307
## Mean : 71.6 Mean :1543 Mean : 375
## 3rd Qu.:102.0 3rd Qu.:1936 3rd Qu.: 438
## Max. :231.0 Max. :3422 Max. :1276
## uninsured_proportion poverty_proportion disability_ratio geometry
## Min. :0.00000 Min. :0.00000 Min. :0.1544 POINT :129
## 1st Qu.:0.01519 1st Qu.:0.03158 1st Qu.:0.4563 epsg:4326 : 0
## Median :0.02785 Median :0.10915 Median :0.4846 +proj=long...: 0
## Mean :0.02763 Mean :0.11735 Mean :0.4799
## 3rd Qu.:0.04421 3rd Qu.:0.21255 3rd Qu.:0.4864
## Max. :0.11557 Max. :0.40153 Max. :0.6808
# Step 1:Count hospitals within 0.25 miles (approximately 402.34 meters)
buffer_distance <- 0.25 * 1609.34 # Convert miles to meters
tract_data_buffered <- st_buffer(tract_data, dist = buffer_distance)
# Spatial join to count hospitals within the buffer
hospital_counts <- st_intersects(tract_data_buffered, yelp_hospital_clean) %>%
lapply(length) %>%
unlist() %>%
data.frame(hospital_count = ., row.names = NULL)
# Combine with tract data
tract_data <- cbind(tract_data, hospital_counts)
# Step 2: Calculate distance to the nearest hospital
# Convert the hospital data to simple feature points
yelp_hospital_points <- st_as_sf(yelp_hospital_clean)
# Calculate the distance to the nearest hospital for each tract
tract_data$nearest_hospital_distance <- st_distance(tract_data, yelp_hospital_points) %>%
apply(1, min) # Find the minimum distance for each tract
# Convert distances to miles
tract_data$nearest_hospital_distance_miles <- tract_data$nearest_hospital_distance / 1609.34
# Step 3: Review the updated tract data
print(head(tract_data[, c("hospital_count", "nearest_hospital_distance", "nearest_hospital_distance_miles")]))
## Simple feature collection with 6 features and 3 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -84.40818 ymin: 33.72657 xmax: -84.11855 ymax: 34.06896
## Geodetic CRS: WGS 84
## hospital_count nearest_hospital_distance nearest_hospital_distance_miles
## 1 0 4904.611 3.04759152
## 2 0 1738.562 1.08029517
## 3 2 181.434 0.11273812
## 4 1 112.488 0.06989696
## 5 0 2034.834 1.26439030
## 6 0 2659.007 1.65223448
## geometry
## 1 MULTIPOLYGON (((-84.19745 3...
## 2 MULTIPOLYGON (((-84.40818 3...
## 3 MULTIPOLYGON (((-84.27626 3...
## 4 MULTIPOLYGON (((-84.37003 3...
## 5 MULTIPOLYGON (((-84.24742 3...
## 6 MULTIPOLYGON (((-84.1484 33...
tract_data <- tract_data %>%
mutate(uninsured_rate = (uninsured_totalE / total_populationE) * 100, # Uninsured rate as a percentage
disability_rate = (population_with_disabilityE / total_populationE) * 100) # Disability rate as a percentage
# tmap mode set to interactive viewing
tmap_mode("view")
map_poverty <- tm_shape(tract_data) +
tm_polygons(col = "poverty_proportion",
style = "quantile",
palette = "Blues",
title = "Poverty Rate") +
tm_shape(yelp_hospital_clean) +
tm_dots(col = "red", size = 0.1, title = "Hospitals", shape = 21, border.col = "black") +
tm_add_legend(type = "symbol",
col = "red",
shape = 21,
size = 1,
title = "Hospitals") +
tm_layout(title = "Poverty Rate by Census Tract with Hospitals",
legend.position = c("right", "bottom"))
map_poverty # Display interactive map for poverty rates
map_uninsured <- tm_shape(tract_data) +
tm_polygons(col = "uninsured_rate",
style = "quantile",
palette = "Reds",
title = "Uninsured Rate (%)") +
tm_shape(yelp_hospital_clean) +
tm_dots(col = "skyblue", size = 0.1, title = "Hospitals", shape = 21, border.col = "black") +
tm_add_legend(type = "symbol",
col = "skyblue",
shape = 21,
size = 1,
title = "Hospitals") +
tm_layout(title = "Uninsured Rate by Census Tract with Hospitals",
legend.position = c("right", "bottom"))
map_uninsured # Display interactive map for uninsured rates
The tracts with the highest poverty rate and uninsured rates are clustered in the southern regions of both counties. Meanwhile, the majority of hospitals are found in the central or northern regions. According to the data, there is a disparity between higher numbers of individuals in poverty as well as those who are uninsured amongst ease of access to hospitals. Therefore, the spatial distribution of hospitals in Fulton and DeKalb counties is not equitable.
# Proportion of Uninsured Population vs. Distance to Nearest Hospital
library(ggplot2)
# Scatter plot of uninsured proportion vs. nearest hospital distance
ggplot(tract_data, aes(x = nearest_hospital_distance_miles, y = uninsured_proportion)) +
geom_point(color = "blue") +
geom_smooth(method = "lm", se = FALSE, color = "red") +
labs(title = "Uninsured Population Proportion vs. Distance to Nearest Hospital",
x = "Distance to Nearest Hospital (miles)",
y = "Uninsured Population Proportion (%)") +
theme_minimal()
# Hospital Count vs. Uninsured Population Proportion
ggplot(tract_data, aes(x = uninsured_proportion, y = hospital_count)) +
geom_point(color = "blue") +
labs(title = "Hospital Count vs. Uninsured Population Proportion",
x = "Uninsured Population Proportion",
y = "Number of Hospitals") +
theme_minimal()
library(ggplot2)
ggplot(tract_data, aes(x = hospital_count, y = poverty_proportion)) +
geom_point(color = "blue") + # Scatter points
geom_smooth(method = "lm", se = FALSE, color = "red") +
labs(title = "Poverty Rate vs. Number of Hospitals",
x = "Number of Hospitals",
y = "Poverty Rate (%)") +
theme_minimal()