Healthy Cities GIS Assignment

Author

Evan Xing

Load the libraries and set the working directory

library(tidyverse)
library(tidyr)
library(leaflet)
cities500 <- read_csv("500CitiesLocalHealthIndicators.cdc.csv")
data(cities500)

The GeoLocation variable has (lat, long) format

Split GeoLocation (lat, long) into two columns: lat and long

latlong <- cities500|>
  mutate(GeoLocation = str_replace_all(GeoLocation, "[()]", ""))|>
  separate(GeoLocation, into = c("lat", "long"), sep = ",", convert = TRUE)
head(latlong)
# A tibble: 6 × 25
   Year StateAbbr StateDesc  CityName  GeographicLevel DataSource Category      
  <dbl> <chr>     <chr>      <chr>     <chr>           <chr>      <chr>         
1  2017 CA        California Hawthorne Census Tract    BRFSS      Health Outcom…
2  2017 CA        California Hawthorne City            BRFSS      Unhealthy Beh…
3  2017 CA        California Hayward   City            BRFSS      Health Outcom…
4  2017 CA        California Hayward   City            BRFSS      Unhealthy Beh…
5  2017 CA        California Hemet     City            BRFSS      Prevention    
6  2017 CA        California Indio     Census Tract    BRFSS      Health Outcom…
# ℹ 18 more variables: UniqueID <chr>, Measure <chr>, Data_Value_Unit <chr>,
#   DataValueTypeID <chr>, Data_Value_Type <chr>, Data_Value <dbl>,
#   Low_Confidence_Limit <dbl>, High_Confidence_Limit <dbl>,
#   Data_Value_Footnote_Symbol <chr>, Data_Value_Footnote <chr>,
#   PopulationCount <dbl>, lat <dbl>, long <dbl>, CategoryID <chr>,
#   MeasureId <chr>, CityFIPS <dbl>, TractFIPS <dbl>, Short_Question_Text <chr>

Filter the dataset

Remove the StateDesc that includes the United Sates, select Prevention as the category (of interest), filter for only measuring crude prevalence and select only 2017.

latlong_clean <- latlong |>
  filter(StateDesc != "United States") |>
  filter(Data_Value_Type == "Crude prevalence") |>
  filter(Year == 2017) |>
  filter(StateAbbr == "CT") |>
  filter(Category == "Unhealthy Behaviors")
head(latlong_clean)
# A tibble: 6 × 25
   Year StateAbbr StateDesc   CityName   GeographicLevel DataSource Category    
  <dbl> <chr>     <chr>       <chr>      <chr>           <chr>      <chr>       
1  2017 CT        Connecticut Bridgeport Census Tract    BRFSS      Unhealthy B…
2  2017 CT        Connecticut Danbury    City            BRFSS      Unhealthy B…
3  2017 CT        Connecticut Norwalk    Census Tract    BRFSS      Unhealthy B…
4  2017 CT        Connecticut Bridgeport Census Tract    BRFSS      Unhealthy B…
5  2017 CT        Connecticut Hartford   Census Tract    BRFSS      Unhealthy B…
6  2017 CT        Connecticut Waterbury  Census Tract    BRFSS      Unhealthy B…
# ℹ 18 more variables: UniqueID <chr>, Measure <chr>, Data_Value_Unit <chr>,
#   DataValueTypeID <chr>, Data_Value_Type <chr>, Data_Value <dbl>,
#   Low_Confidence_Limit <dbl>, High_Confidence_Limit <dbl>,
#   Data_Value_Footnote_Symbol <chr>, Data_Value_Footnote <chr>,
#   PopulationCount <dbl>, lat <dbl>, long <dbl>, CategoryID <chr>,
#   MeasureId <chr>, CityFIPS <dbl>, TractFIPS <dbl>, Short_Question_Text <chr>

What variables are included? (can any of them be removed?)

names(latlong_clean)
 [1] "Year"                       "StateAbbr"                 
 [3] "StateDesc"                  "CityName"                  
 [5] "GeographicLevel"            "DataSource"                
 [7] "Category"                   "UniqueID"                  
 [9] "Measure"                    "Data_Value_Unit"           
[11] "DataValueTypeID"            "Data_Value_Type"           
[13] "Data_Value"                 "Low_Confidence_Limit"      
[15] "High_Confidence_Limit"      "Data_Value_Footnote_Symbol"
[17] "Data_Value_Footnote"        "PopulationCount"           
[19] "lat"                        "long"                      
[21] "CategoryID"                 "MeasureId"                 
[23] "CityFIPS"                   "TractFIPS"                 
[25] "Short_Question_Text"       

Remove the variables that will not be used in the assignment

latlong_clean2 <- latlong_clean |>
  select(-DataSource,-Data_Value_Unit, -DataValueTypeID, -Low_Confidence_Limit, -High_Confidence_Limit, -Data_Value_Footnote_Symbol, -Data_Value_Footnote)
head(latlong_clean2)
# A tibble: 6 × 18
   Year StateAbbr StateDesc   CityName GeographicLevel Category UniqueID Measure
  <dbl> <chr>     <chr>       <chr>    <chr>           <chr>    <chr>    <chr>  
1  2017 CT        Connecticut Bridgep… Census Tract    Unhealt… 0908000… Obesit…
2  2017 CT        Connecticut Danbury  City            Unhealt… 918430   Obesit…
3  2017 CT        Connecticut Norwalk  Census Tract    Unhealt… 0955990… Obesit…
4  2017 CT        Connecticut Bridgep… Census Tract    Unhealt… 0908000… Curren…
5  2017 CT        Connecticut Hartford Census Tract    Unhealt… 0937000… Obesit…
6  2017 CT        Connecticut Waterbu… Census Tract    Unhealt… 0980000… Obesit…
# ℹ 10 more variables: Data_Value_Type <chr>, Data_Value <dbl>,
#   PopulationCount <dbl>, lat <dbl>, long <dbl>, CategoryID <chr>,
#   MeasureId <chr>, CityFIPS <dbl>, TractFIPS <dbl>, Short_Question_Text <chr>

The new dataset “Prevention” is a manageable dataset now.

For your assignment, work with a cleaned dataset.

1. Once you run the above code and learn how to filter this complicated dataset, perform your own investigation by filtering this dataset however you choose so that you have a subset with no more than 900 observations.

Filter chunk here (you may need multiple chunks)

latlong_MD_Diabetes <- latlong |> filter (StateAbbr == "MD", GeographicLevel == "Census Tract",
         Year == 2017,
         Data_Value_Type == "Crude prevalence",
         Category == "Health Outcomes",
         Measure == "Diagnosed diabetes among adults aged >=18 Years", !is.na(Data_Value))

head(latlong_MD_Diabetes)
# A tibble: 6 × 25
   Year StateAbbr StateDesc CityName  GeographicLevel DataSource Category       
  <dbl> <chr>     <chr>     <chr>     <chr>           <chr>      <chr>          
1  2017 MD        Maryland  Baltimore Census Tract    BRFSS      Health Outcomes
2  2017 MD        Maryland  Baltimore Census Tract    BRFSS      Health Outcomes
3  2017 MD        Maryland  Baltimore Census Tract    BRFSS      Health Outcomes
4  2017 MD        Maryland  Baltimore Census Tract    BRFSS      Health Outcomes
5  2017 MD        Maryland  Baltimore Census Tract    BRFSS      Health Outcomes
6  2017 MD        Maryland  Baltimore Census Tract    BRFSS      Health Outcomes
# ℹ 18 more variables: UniqueID <chr>, Measure <chr>, Data_Value_Unit <chr>,
#   DataValueTypeID <chr>, Data_Value_Type <chr>, Data_Value <dbl>,
#   Low_Confidence_Limit <dbl>, High_Confidence_Limit <dbl>,
#   Data_Value_Footnote_Symbol <chr>, Data_Value_Footnote <chr>,
#   PopulationCount <dbl>, lat <dbl>, long <dbl>, CategoryID <chr>,
#   MeasureId <chr>, CityFIPS <dbl>, TractFIPS <dbl>, Short_Question_Text <chr>

Created a dataset called “Latlong_MD_Diabetes” that contains Maryland specific data for diagnosed diatetes among adults aged >=18 years without na values. All Maryland Data is from Baltimore, 2017.

latlong_MD_Diabetes <- latlong_MD_Diabetes |> select(-DataSource,-Data_Value_Unit, -DataValueTypeID, -Low_Confidence_Limit, -High_Confidence_Limit, -Data_Value_Footnote_Symbol, -Data_Value_Footnote)



nrow(latlong_MD_Diabetes)
[1] 199

Removed unused variables(Which isn’t really necessary) and checks observation count(199 observations)

2. Based on the GIS tutorial (Japan earthquakes), create one plot about something in your subsetted dataset.

First plot chunk here

ggplot(latlong_MD_Diabetes, aes(x = Data_Value)) +
  geom_histogram(binwidth = 2, fill = "red", color = "white") +
  theme_classic() +
  labs( title = "Adult Diabetes Prevalence MD Census Tracts, 2017", x = "Crude Adult Diabetes Prevalence (%)", y = "Number of Census Tracts", caption = "Source: CDC 500 Cities Project")

This is a histogram showing the number of census tracts(defined geographical areas, in my case: Baltimore, MD) that fall into specific bins for crude adult prevalence rate of diabetes. Each bin is 2% percentage points wide.

3. Now create a map of your subsetted dataset.

First map chunk here

diabetes_pal <- colorNumeric(palette = "Reds", domain = latlong_MD_Diabetes$Data_Value)

leaflet(latlong_MD_Diabetes) |> setView( lng = -76.61, lat = 39.29, zoom = 11) |> addTiles() |>
  addCircleMarkers(lng = ~long, lat = ~lat, radius = 6, color = ~diabetes_pal(Data_Value), fillColor = ~diabetes_pal(Data_Value), fillOpacity = 0.7, stroke = FALSE) |>
  addLegend( position = "bottomright", pal = diabetes_pal, values = ~Data_Value, title = "Diabetes Prevalence (%)"
  )

This interactive map displays the estimated crude prevalence of diagnosed diabetes among adults for census tracts in Baltimore, Maryland. Each circle represents a census tract. Darker red circles indicate census tracts with higher estimated diabetes prevalence. The leaflet plot is set to central baltimore at approximately city level resolution/scale. Uses a red color scale for diabetes prevalence in both the legend and circles representing each census tract. Using addTiles(), Adds a real background map of baltimore to plot the lat. and long. of each census tract, represented by the circles. Stroke= false removes the background border for each circle.The legend is positioned towards the bottom right corner as I felt that made most sense visually to maximize readability of the map. Created a color scale for the continous variable, Data_value, which contains crude diabetes prevalence rate values, using colorNumeric. The color palette is set to red.

4. Refine your map to include a mouse-click tooltip

Refined map chunk here

leaflet(latlong_MD_Diabetes) |> setView( lng = -76.61, lat = 39.29, zoom = 11) |> addTiles() |>
  addCircleMarkers( lng = ~long,lat = ~lat, radius = 6, color = ~diabetes_pal(Data_Value), fillColor = ~diabetes_pal(Data_Value), fillOpacity = 0.7, stroke = FALSE,
    popup = ~paste0( "<b>Census Tract:</b> ", TractFIPS, "<br><b>Diabetes Prevalence:</b> ", Data_Value, "%","<br><b>Population:</b> ", PopulationCount)) |>
  addLegend( position = "bottomright", pal = diabetes_pal, values = ~Data_Value, title = "Diabetes Prevalence (%)")

5. Write a paragraph

In a paragraph, describe the plots you created and what they show.

The Leaflet maps show the geographic distribution of estimated adult diabetes prevalence from census tracts in Baltimore, Maryland, in 2017. Each circle represents a census tract and is positioned using the latitude and longitude associated with each tract. The color of each circle represents the crude prevalence of diagnosed diabetes among adults age 18 and older. The darker the red indicating higher estimated prevalence and the lighter the red indicating lower prevalence. The refined map using the popup argument also allows the user to click on each circle to view its census tract’s FIPS code, estimated diabetes prevalence, and population count. Overall, the maps make it easier to see how diabetes prevalence varies geographically across different parts of Baltimore, especially when compared to a histogram, which can not physical show on a map where each census tract is and its diabetes prevalence found there.