# rebuild a clean GEOID (I was getting mostly NA values for some reason for GEOID)tx_census_tracts <- tx_census_tracts %>%mutate(GEOID_clean =paste0(STATEFP, COUNTYFP, TRACTCE) )# checkhead(tx_census_tracts$GEOID_clean)
# double check#unique(census_tracts$GEOID_clean)# inspect new GEOIDs in Exceltract_ids <-unique(tx_census_tracts$GEOID_clean)write.csv(tract_ids, "All_Census_Tract_GEOIDs.csv", row.names =FALSE)# there are 6,896 tracts in Texas according to this list
# make sure both layers have valid geometryaustin_jur_filtered <-st_make_valid(austin_jur_filtered)tx_census_tracts <-st_make_valid(tx_census_tracts)
# quick check that the selected tracts look reasonableprint(paste("# of tracts intersecting Austin:", nrow(selected_tracts)))
[1] "# of tracts intersecting Austin: 383"
print(paste("# of unique GEOIDs:", length(unique(selected_tracts$GEOID_clean))))
[1] "# of unique GEOIDs: 271"
There are 271 intersecting census tracts, meaning there are 271 tracts in Austin full and limited purpose jurisdictions. This makes sense, as Travis County alone has 291 census tracts, though not all of Travis County is in Austin. There are a total of 493 census tracts in all of Bastrop, Hays, Travis, and Williamson Counties combined.
The reason there are 383 rows, but only 271 distinct tracts, could be because some tracts may touch multiple Austin jurisdiction polygons since Austin’s boundary is split into parts.
# quick view of unique GEOIDsprint(sort(unique(selected_tracts$GEOID_clean))[1:20])
# to save only distinct GEOIDs with no duplicatesselected_unique <- selected_tracts %>%distinct(GEOID_clean, .keep_all =TRUE)
Save Final Files
# save the intersected tracts shapefilest_write(selected_tracts, "Austin_LTD_FULL_Tracts.shp")
Warning in abbreviate_shapefile_names(obj): Field names abbreviated for ESRI
Shapefile driver
Writing layer `Austin_LTD_FULL_Tracts' to data source
`Austin_LTD_FULL_Tracts.shp' using driver `ESRI Shapefile'
Writing 383 features with 24 fields and geometry type Polygon.
# Also export a CSV list of tract GEOIDs and namestract_list <- selected_tracts %>%st_drop_geometry() %>%arrange(GEOID_clean)write_csv(tract_list, "Austin_LTD_FULL_Tract_List.csv")#################################################################################### files without duplicate GEOIDsst_write(selected_unique, "Austin_LTD_FULL_Tracts_Unique.shp")
Warning in abbreviate_shapefile_names(obj): Field names abbreviated for ESRI
Shapefile driver
Writing layer `Austin_LTD_FULL_Tracts_Unique' to data source
`Austin_LTD_FULL_Tracts_Unique.shp' using driver `ESRI Shapefile'
Writing 271 features with 24 fields and geometry type Polygon.
Checking to see if I still get 271 tracts when I join my shapefile to Coda’s shapefile. Coda’s shapefile contains all census tracts in Bastrop, Hays, Travis, and Williamson counties.
# check which of my 271 unique GEOIDs are in Coda's filecommon_geo <-intersect(unique(selected_unique$GEOID_clean),unique(CRG_tracts$GEOID_clean))setdiff(unique(selected_unique$GEOID_clean), unique(CRG_tracts$GEOID_clean)) # not in CRG's file
character(0)
length(CRG_tracts$GEOID_clean)
[1] 492
# how many unique GEOID's in Coda's filelength(unique(CRG_tracts$GEOID_clean))
[1] 492
length(common_geo)
[1] 271
Verified that all 271 tracts are in Coda’s file.
Revised Analysis (Exclude Biasing Tracts)
After talking to Coda, we realized some tracts are biasing the analysis, as they barely fall partially within the bounds of Austin. This revised analysis excludes tracts that are less than 10% inside the Austin boundaries.
# union Austin boundary into a single polygonaustin_union <-st_union(austin_jur_filtered)# project both Austin union and unique tracts into an equal-area CRS# using EPSG:3083 (Texas Centric Albers) — same as Coda usedaustin_a <-st_transform(austin_union, 3083)tracts_a <-st_transform(selected_unique, 3083)# intersection pieces representing portion of each tract inside Austininside_pieces <-st_intersection( tracts_a %>%select(GEOID_clean, COUNTYFP),st_sf(geometry = austin_a))
Warning: attribute variables are assumed to be spatially constant throughout
all geometries
# exclude tracts with less than 10% of area inside Austinselected_10pct <- selected_strict %>%filter(pct_in_austin >=10)# check how many are excluded and how many remainn_before <-nrow(selected_unique)n_after <-nrow(selected_10pct)n_excluded <- n_before - n_afterprint(paste("Original unique tracts:", n_before))
[1] "Original unique tracts: 271"
print(paste("Tracts after excluding <10% overlaps:", n_after))
[1] "Tracts after excluding <10% overlaps: 250"
print(paste("Number of tracts excluded:", n_excluded))
[1] "Number of tracts excluded: 21"
# ensure 21 were excludedif (n_excluded >=20& n_excluded <=22) {print("exclusion test passed: 21 tracts removed")} else {warning("you got something different from coda!!!!")}
[1] "exclusion test passed: 21 tracts removed"
# save new outputs# save the 10% filtered shapefilest_write(selected_10pct, "Austin_LTD_FULL_Tracts_10pct_Intersect.shp")
Warning in abbreviate_shapefile_names(obj): Field names abbreviated for ESRI
Shapefile driver
Writing layer `Austin_LTD_FULL_Tracts_10pct_Intersect' to data source
`Austin_LTD_FULL_Tracts_10pct_Intersect.shp' using driver `ESRI Shapefile'
Writing 250 features with 25 fields and geometry type Polygon.
# export csv of the remaining tractsstrict_tract_list <- selected_10pct %>%st_drop_geometry() %>%select(GEOID_clean, NAME, NAMELSAD, pct_in_austin) %>%arrange(GEOID_clean)write_csv(strict_tract_list, "Austin_LTD_FULL_Tract_List_10pct.csv")
# identify excluded tracts (those with < 10% area in Austin)excluded_tracts <- selected_strict %>%filter(pct_in_austin <10)# check countprint(paste("Excluded tracts:", nrow(excluded_tracts)))
# creating a map to highlight Williamson & Hays Tracts# I need a better idea of where these tracts are located in relation to Travis County tracts. For our evictions indicator, we only have Travis County data. We may need to take averages of surrounding Travis County tracts to use for Williamson and Hays.library(tmap)
Warning: package 'tmap' was built under R version 4.5.2
# static mode for Quarto embeddingtmap_mode("plot")
ℹ tmap modes "plot" - "view"
ℹ toggle with `tmap::ttm()`
── tmap v3 code detected ───────────────────────────────────────────────────────
[v3->v4] `tm_tm_polygons()`: migrate the argument(s) related to the scale of
the visual variable `fill` namely 'palette' (rename to 'values') to fill.scale
= tm_scale(<HERE>).[v3->v4] `tm_polygons()`: use 'fill' for the fill color of polygons/symbols
(instead of 'col'), and 'col' for the outlines (instead of 'border.col').[v3->v4] `tm_polygons()`: use `fill_alpha` instead of `alpha`.[v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the
visual variable `fill` namely 'title' to 'fill.legend = tm_legend(<HERE>)'[v3->v4] `tm_layout()`: use `tm_title()` instead of `tm_layout(main.title = )`
final_map
# save map as PNGtmap_save( final_map,filename ="Austin_full_limited.png",width =10,height =8,units ="in",dpi =300)
Map saved to C:\Users\kaitl\OneDrive\Documents\Every Texan\R\City of Austin Equity Index\Full and LTD census tracts\Austin_full_limited.png
Resolution: 3000 by 2400 pixels
Size: 10 by 8 inches (300 dpi)
Calculating Eviction Averages for Williamson and Hays Tracts
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `eviction_clean = readr::parse_number(`Eviction filing rate`)`.
Caused by warning:
! 20 parsing failures.
row col expected actual
2 -- a number -
26 -- a number -
33 -- a number -
35 -- a number -
79 -- a number -
... ... ........ ......
See problems(...) for more details.
##### 3. Keep only usable rowsevictions_clean <- evictions_raw %>%filter(!is.na(GEOID_clean),!is.na(eviction_clean) ) %>%select(GEOID_clean, eviction_clean)##### 4. Join to Austin tractstracts_with_evictions <- selected_10pct %>%left_join(evictions_clean, by ="GEOID_clean")##### 5. Split Travis vs non-Travisevict_col <-"eviction_clean"travis_tracts <- tracts_with_evictions %>%filter(COUNTYFP =="453")non_travis_tracts <- tracts_with_evictions %>%filter(COUNTYFP !="453")# keep only Travis tracts with real datatravis_valid <- travis_tracts %>%filter(!is.na(.data[[evict_col]]))##### 6. Find touching neighborstouch_neighbors <-st_touches( non_travis_tracts, travis_tracts)##### 7. Compute centroids in projected CRS (for distance)non_proj <-st_transform(non_travis_tracts, 3083)travis_proj <-st_transform(travis_valid, 3083)non_cent <-st_centroid(non_proj)
Warning: st_centroid assumes attributes are constant over geometries
travis_cent <-st_centroid(travis_proj)
Warning: st_centroid assumes attributes are constant over geometries
# save for documentationwrite_csv( touch_table,"Austin_NonTravis_Touching_Travis_Evictions.csv")################################################################################