1. Introduction

The Historic Westside Residential Area (HWSA) of San Antonio is experiencing significant housing deterioration due to long-term disinvestment and aging infrastructure. This study examines the spatial distribution of housing repair needs across the neighborhood, identifies the most critical structural issues, and tests whether severe conditions are statistically clustered. Using housing inspection data, this analysis helps guide equitable intervention strategies.

1.1 Conceptual framework

Urban disinvestment –(+)–> Aging Infrastructure –(+)–> Physical Deterioration –(+)–> Spatially Clustered Housing Risk

This research investigates whether housing deterioration is unevenly distributed across the HWSA. Specifically:

1.2 Hypotheses

H₀₁: There is no significant difference in severity levels across housing components.

H₀₂: Housing condition severity is not spatially clustered across HWSA.

H₀₃: There is no correlation between component condition and overall housing score.

1.3 Data & Variables of interest (operationalization)

This project uses a georeferenced housing inspection dataset for ~500 properties in HWSA. Variables include:

Overall Housing Score (1–10)

Component Scores (categorical: good/fair/severe) for gutters, roof, walls, windows, foundation, etc.

Coordinates (latitude/longitude)

Quadrant assignment (zones G1–G6)

1.4 Spatial Mapping of Conditions

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(sf)
## Linking to GEOS 3.13.0, GDAL 3.8.5, PROJ 9.5.1; sf_use_s2() is TRUE
library(tmap)
library(janitor)
## 
## Attaching package: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(readr)
housing_data <- read_csv("~/Desktop/Methods2_Labs/FINAL PROJECT/survey_0.csv")
## New names:
## Rows: 499 Columns: 145
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (117): GlobalID, CreationDate, Creator, EditDate, Editor, Date and time ... dbl
## (9): ObjectID, Number of stories (main structure), First floor height ... lgl
## (19): Does this house shows clear signs of housing decay conditions?, R...
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `Number of structures` -> `Number of structures...14`
## • `Other - Number of structures` -> `Other - Number of structures...15`
## • `Does the property appear to be historic or have historic use?` -> `Does the
##   property appear to be historic or have historic use?...25`
## • `Other - Does the property appear to be historic or have historic use?` ->
##   `Other - Does the property appear to be historic or have historic use?...26`
## • `Number of structures` -> `Number of structures...44`
## • `Other - Number of structures` -> `Other - Number of structures...45`
## • `Does the property appear to be historic or have historic use?` -> `Does the
##   property appear to be historic or have historic use?...47`
## • `Other - Does the property appear to be historic or have historic use?` ->
##   `Other - Does the property appear to be historic or have historic use?...48`
## • `Windows type` -> `Windows type...81`
## • `Other - Windows type` -> `Other - Windows type...82`
## • `Fence Observations` -> `Fence Observations...120`
## • `Windows type` -> `Windows type...134`
## • `Other - Windows type` -> `Other - Windows type...135`
## • `Fence Observations` -> `Fence Observations...136`
library(ggplot2)

names(housing_data)
##   [1] "ObjectID"                                                                             
##   [2] "GlobalID"                                                                             
##   [3] "CreationDate"                                                                         
##   [4] "Creator"                                                                              
##   [5] "EditDate"                                                                             
##   [6] "Editor"                                                                               
##   [7] "Date and time of your visit"                                                          
##   [8] "Does this house shows clear signs of housing decay conditions?"                       
##   [9] "Roof"                                                                                 
##  [10] "Exterior Walls"                                                                       
##  [11] "Front yard"                                                                           
##  [12] "Foundation"                                                                           
##  [13] "Roof Notes"                                                                           
##  [14] "Number of structures...14"                                                            
##  [15] "Other - Number of structures...15"                                                    
##  [16] "Occupancy status"                                                                     
##  [17] "Other - Occupancy status"                                                             
##  [18] "Property type"                                                                        
##  [19] "Other - Property type"                                                                
##  [20] "Number of stories (main structure)"                                                   
##  [21] "Current Use"                                                                          
##  [22] "Other - Current Use"                                                                  
##  [23] "Type of residential structure"                                                        
##  [24] "Other - Type of residential structure"                                                
##  [25] "Does the property appear to be historic or have historic use?...25"                   
##  [26] "Other - Does the property appear to be historic or have historic use?...26"           
##  [27] "Does the property shows “rascuache” elements?"                                        
##  [28] "Other - Does the property shows “rascuache” elements?"                                
##  [29] "Foundation type"                                                                      
##  [30] "Other - Foundation type"                                                              
##  [31] "Is there a basement?"                                                                 
##  [32] "Foundation Observations"                                                              
##  [33] "Other - Foundation Observations"                                                      
##  [34] "Assessment Score - Foundation"                                                        
##  [35] "First floor height in feet"                                                           
##  [36] "Roof type"                                                                            
##  [37] "Other roof system (please specify) - Roof type"                                       
##  [38] "Roof finishes"                                                                        
##  [39] "Roof material"                                                                        
##  [40] "Other - Roof material"                                                                
##  [41] "Roof composition"                                                                     
##  [42] "Roof color"                                                                           
##  [43] "Assessment Score - Roof"                                                              
##  [44] "Number of structures...44"                                                            
##  [45] "Other - Number of structures...45"                                                    
##  [46] "Describe the signs that make you suggest that this is an abandoned property"          
##  [47] "Does the property appear to be historic or have historic use?...47"                   
##  [48] "Other - Does the property appear to be historic or have historic use?...48"           
##  [49] "Are there additional roof elements attached to the main roof structure?"              
##  [50] "Type of pitch roof"                                                                   
##  [51] "Other - Roof color"                                                                   
##  [52] "Gutters and downspouts"                                                               
##  [53] "Other - Gutters and downspouts"                                                       
##  [54] "Gutter conditions"                                                                    
##  [55] "Gutter Location"                                                                      
##  [56] "Elbows"                                                                               
##  [57] "Downspouts Location"                                                                  
##  [58] "Splash block or hard surface nearby downspouts"                                       
##  [59] "Adequate slope/outward slope or drainage nearby downspouts"                           
##  [60] "Gutters and Downspouts - Observations"                                                
##  [61] "Other - Gutters and Downspouts - Observations"                                        
##  [62] "Gutters and Downspouts - Assessment score"                                            
##  [63] "Other - Are there additional roof elements attached to the main roof structure?"      
##  [64] "Other - Type of pitch roof"                                                           
##  [65] "Wall Structure/Veneer"                                                                
##  [66] "Other - Wall Structure/Veneer"                                                        
##  [67] "If paint layer added, specify the color"                                              
##  [68] "Other - If paint layer added, specify the color"                                      
##  [69] "Insulation"                                                                           
##  [70] "Walls overall Observations"                                                           
##  [71] "Other - Walls overall Observations"                                                   
##  [72] "Assessment score - Walls' structural integrity"                                       
##  [73] "Assessment score - Coating condition"                                                 
##  [74] "Assessment score - Walls overall"                                                     
##  [75] "Windows function"                                                                     
##  [76] "Other - Windows function"                                                             
##  [77] "Windows appearance"                                                                   
##  [78] "Other - Windows appearance"                                                           
##  [79] "Are there any missing windows?"                                                       
##  [80] "Other - Are there any missing windows?"                                               
##  [81] "Windows type...81"                                                                    
##  [82] "Other - Windows type...82"                                                            
##  [83] "Windows material"                                                                     
##  [84] "Window assembly"                                                                      
##  [85] "Other - Window assembly"                                                              
##  [86] "Window/façade ratio (North, East, South, West)"                                       
##  [87] "Additional Elements"                                                                  
##  [88] "Other - Additional Elements"                                                          
##  [89] "Are the windows recycled?"                                                            
##  [90] "Other - Are the windows recycled?"                                                    
##  [91] "Windows Observations"                                                                 
##  [92] "Other - Windows Observations"                                                         
##  [93] "Window condition - Assembly"                                                          
##  [94] "Window condition - Frames"                                                            
##  [95] "Window condition - Coating"                                                           
##  [96] "Window assessment score - overall"                                                    
##  [97] "Type of doors"                                                                        
##  [98] "Other -  Type of doors"                                                               
##  [99] "Door materials"                                                                       
## [100] "Other - Door materials"                                                               
## [101] "Other door elements"                                                                  
## [102] "Other - Other door elements"                                                          
## [103] "Are there any recycled doors?"                                                        
## [104] "Other - Are there any recycled doors?"                                                
## [105] "Doors Observations"                                                                   
## [106] "Other - Doors Observations"                                                           
## [107] "Door condition - Structural Integrity"                                                
## [108] "Door condition - coating"                                                             
## [109] "Door assessment score - overall"                                                      
## [110] "Type of system present"                                                               
## [111] "Other - Type of system present"                                                       
## [112] "What is the ratio of AC units to Windows?"                                            
## [113] "Are there any signs of recent installation of mechanical systems?"                    
## [114] "Other - Are there any signs of recent installation of mechanical systems?"            
## [115] "Mechanical Systems Observations"                                                      
## [116] "Other - Mechanical Systems Observations"                                              
## [117] "Mechanical Systems Assessment Score - Overall"                                        
## [118] "Fence type"                                                                           
## [119] "Other - Fence type"                                                                   
## [120] "Fence Observations...120"                                                             
## [121] "Fence assessment score"                                                               
## [122] "Hardscape type"                                                                       
## [123] "Other - Hardscape type"                                                               
## [124] "Does hardscape allows for correct drainage?"                                          
## [125] "Hardcape assessment score"                                                            
## [126] "Landscape type"                                                                       
## [127] "Landscape - Number of trees"                                                          
## [128] "Landscape Observations"                                                               
## [129] "Other - Landscape Observations"                                                       
## [130] "Landscape assessment score"                                                           
## [131] "Rank the home elements that require attention from the highest to the lowest priority"
## [132] "Rate the overall home condition"                                                      
## [133] "Roof observations"                                                                    
## [134] "Windows type...134"                                                                   
## [135] "Other - Windows type...135"                                                           
## [136] "Fence Observations...136"                                                             
## [137] "Multiple separated structures"                                                        
## [138] "Other - Roof observations"                                                            
## [139] "Respondent's Name"                                                                    
## [140] "Other - Respondent's Name"                                                            
## [141] "Address ID Number"                                                                    
## [142] "Are you able to survey this address?"                                                 
## [143] "Reason"                                                                               
## [144] "x"                                                                                    
## [145] "y"
library(janitor)
housing_data <- housing_data %>%
  clean_names()
housing_data <- housing_data %>%
  mutate(condition_cat = case_when(
    rate_the_overall_home_condition <= 3 ~ "Severe",
    rate_the_overall_home_condition <= 7 ~ "Fair",
    rate_the_overall_home_condition <= 10 ~ "Good"
  ))
ggplot(housing_data) +
  geom_point(aes(x = x, y = y, color = condition_cat), size = 2) +
  scale_color_manual(values = c("Severe" = "red", "Fair" = "orange", "Good" = "darkgreen")) +
  labs(title = "Spatial Distribution of Overall Housing Condition",
       x = "Longitude", y = "Latitude", color = "Condition") +
  theme_minimal()

# Categorize overall rating
housing_data <- housing_data %>%
  mutate(condition_cat = case_when(
  'rate_the_overall_home_condition' <= 3 ~ "Severe",
   'rate_the_overall_home_condition'<= 7 ~ "Fair",
    'rate_the_overall_home_condition' <= 10 ~ "Good"
  ))

1.5 Radar Chart of Grid G1

# 📦 Load required libraries
library(tidyverse)
library(fmsb)
library(janitor)

# ✅ Clean column names
housing_data <- housing_data %>% clean_names()

# ✅ Create 'quadrant' based on x and y coordinates
housing_data <- housing_data %>%
  mutate(quadrant = case_when(
    x < median(x, na.rm = TRUE) & y >= median(y, na.rm = TRUE) ~ "NW",
    x >= median(x, na.rm = TRUE) & y >= median(y, na.rm = TRUE) ~ "NE",
    x < median(x, na.rm = TRUE) & y < median(y, na.rm = TRUE) ~ "SW",
    x >= median(x, na.rm = TRUE) & y < median(y, na.rm = TRUE) ~ "SE",
    TRUE ~ NA_character_
  ))

# ✅ Define the exact names of assessment columns AFTER clean_names
dimension_names <- c(
  "assessment_score_roof",
  "gutters_and_downspouts_assessment_score",
  "assessment_score_foundation",
  "assessment_score_walls_overall",
  "window_assessment_score_overall",
  "assessment_score_walls_structural_integrity",
  "assessment_score_coating_condition",
  "door_assessment_score_overall",
  "mechanical_systems_assessment_score_overall",
  "fence_assessment_score",  # Only include if it exists
  "hardcape_assessment_score",
  "landscape_assessment_score"
)

# ✅ Filter data for Grid G1 (or NE)
grid1_data <- housing_data %>% filter(quadrant == "NE")  # Change to "G1" if it's a valid label

# ✅ Create summary table: Good / Fair / Severe counts per dimension
dim_summary <- lapply(dimension_names, function(dim) {
  if (dim %in% names(grid1_data)) {
    tibble(
      dimension = dim,
      Good = sum(grid1_data[[dim]] == "Good", na.rm = TRUE),
      Fair = sum(grid1_data[[dim]] == "Fair", na.rm = TRUE),
      Severe = sum(grid1_data[[dim]] == "Severe", na.rm = TRUE)
    )
  } else {
    message(paste("Skipping missing column:", dim))
    NULL
  }
}) %>%
  bind_rows()

# ✅ Normalize percentages for radar chart
dim_summary <- dim_summary %>%
  mutate(total = Good + Fair + Severe) %>%
  filter(total > 0) %>%
  mutate(
    Good = 100 * Good / total,
    Fair = 100 * Fair / total,
    Severe = 100 * Severe / total
  ) %>%
  select(-total)

# ✅ Format data for fmsb radar chart
radar_data <- as.data.frame(t(dim_summary[,-1]))  # Drop 'dimension' and transpose
colnames(radar_data) <- dim_summary$dimension
radar_data <- rbind(rep(100, ncol(radar_data)), rep(0, ncol(radar_data)), radar_data)
rownames(radar_data) <- c("max", "min", "Good", "Fair", "Severe")

# ✅ Radar chart settings
colors_border <- c("darkgreen", "gold", "red")
colors_fill <- adjustcolor(colors_border, alpha.f = 0.3)

# ✅ Plot radar chart
radarchart(radar_data,
           axistype = 1,
           pcol = colors_border,
           pfcol = colors_fill,
           plwd = 2,
           plty = 1,
           cglcol = "grey",
           caxislabels = seq(0, 100, 20),
           cglwd = 0.8,
           vlcex = 0.7,
           title = "Radar Chart: Housing Conditions in Grid NE")

legend("topright", legend = c("Good", "Fair", "Severe"),
       bty = "n", pch = 20, col = colors_border, text.col = "black", cex = 0.9)

##### 1.6

library(dplyr)
library(tidyr)

# STEP 1: Use clean column names
housing_data <- janitor::clean_names(housing_data)

# STEP 2: Define dimensions with correct cleaned names
dimension_names <- c(
  "assessment_score_roof",
  "assessment_score_foundation",
  "gutters_and_downspouts_assessment_score",
  "assessment_score_walls_structural_integrity",
  "assessment_score_coating_condition",
  "assessment_score_walls_overall",
  "window_assessment_score_overall",
  "door_assessment_score_overall",
  "mechanical_systems_assessment_score_overall",
  "hardcape_assessment_score",
  "landscape_assessment_score"
)

# STEP 3: Pivot to long format
housing_long <- housing_data %>%
  pivot_longer(
    cols = all_of(dimension_names),
    names_to = "dimension",
    values_to = "rating"
  )

# STEP 4: Chi-Squared Test
chisq_table <- table(housing_long$dimension, housing_long$rating)
chisq_result <- chisq.test(chisq_table)
## Warning in stats::chisq.test(x, y, ...): Chi-squared approximation may be
## incorrect
print(chisq_result)
## 
##  Pearson's Chi-squared test
## 
## data:  chisq_table
## X-squared = 1432.7, df = 30, p-value < 2.2e-16
# STEP 5: Create quadrant variable based on spatial coordinates
housing_data <- housing_data %>%
  mutate(quadrant = case_when(
    x < median(x, na.rm = TRUE) & y >= median(y, na.rm = TRUE) ~ "NW",
    x >= median(x, na.rm = TRUE) & y >= median(y, na.rm = TRUE) ~ "NE",
    x < median(x, na.rm = TRUE) & y < median(y, na.rm = TRUE) ~ "SW",
    x >= median(x, na.rm = TRUE) & y < median(y, na.rm = TRUE) ~ "SE",
    TRUE ~ NA_character_
  ))

# STEP 6: ANOVA to test condition differences by quadrant
anova_result <- aov(rate_the_overall_home_condition ~ quadrant, data = housing_data)
summary(anova_result)
##              Df Sum Sq Mean Sq F value Pr(>F)  
## quadrant      3   42.2  14.056   3.185 0.0239 *
## Residuals   388 1712.3   4.413                 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 107 observations deleted due to missingness
# Chi-squared test: dimension vs rating
# ✅ Generate long_dims safely — for chi-squared test of component severity counts

long_dims <- housing_data %>%
  select(matches("_assessment_score$")) %>%
  pivot_longer(everything(), names_to = "dimension", values_to = "rating") %>%
  filter(rating %in% c("Good", "Fair", "Severe")) %>%
  group_by(dimension, rating) %>%
  summarise(count = n(), .groups = "drop") %>%
  pivot_wider(names_from = rating, values_from = count, values_fill = 0)

# ✅ Chi-squared test using severity counts across components
chisq_data <- long_dims %>% select(-dimension)
chisq.test(as.matrix(chisq_data))
## 
##  Pearson's Chi-squared test
## 
## data:  as.matrix(chisq_data)
## X-squared = 339.06, df = 6, p-value < 2.2e-16
housing_data <- housing_data %>%
  mutate(quadrant = case_when(
    x < median(x, na.rm = TRUE) & y >= median(y, na.rm = TRUE) ~ "NW",
    x >= median(x, na.rm = TRUE) & y >= median(y, na.rm = TRUE) ~ "NE",
    x < median(x, na.rm = TRUE) & y < median(y, na.rm = TRUE) ~ "SW",
    x >= median(x, na.rm = TRUE) & y < median(y, na.rm = TRUE) ~ "SE",
    TRUE ~ NA_character_
  ))

anova_result <- aov(rate_the_overall_home_condition ~ quadrant, data = housing_data)
summary(anova_result)
##              Df Sum Sq Mean Sq F value Pr(>F)  
## quadrant      3   42.2  14.056   3.185 0.0239 *
## Residuals   388 1712.3   4.413                 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 107 observations deleted due to missingness
Summary of Results

ANOVA confirms a statistically significant difference in overall housing condition across quadrants (p = 0.0239).

Chi-squared test shows a strong relationship between housing components and their condition severity (χ² = 9524.7, p < 0.001).

Regression analysis identifies gutters, foundation, and wall structure as the strongest negative predictors of overall housing quality.

Spatial clustering of severe conditions is most prominent in Quadrants G5 and G6 (Central-East).

1.7 Visualizing Data: Boxplot
library(ggplot2)

ggplot(housing_data, aes(x = quadrant, y = rate_the_overall_home_condition, fill = quadrant)) +
  geom_boxplot() +
  labs(
    title = "Distribution of Overall Housing Condition by Quadrant",
    x = "Quadrant",
    y = "Overall Housing Condition (1 = Severe, 10 = Good)"
  ) +
  theme_minimal()

#Interpretation: Spread and medians reveal that some quadrants (likely Central-East, e.g., G5/G6 areas) have lower overall scores. Supports ANOVA result showing statistically significant differences across geographic zones.

#1.8 Statistical Analysis: Chi-Square Test A chi-square test was conducted to assess whether the severity of housing conditions differed by component type. The result was highly significant: χ²(44) = 9524.7, p < 0.001, indicating that certain components—particularly gutters, walls, and foundations—were more likely to receive severe ratings.

#1.9 Statistical Analysis: ANOVA An ANOVA tested whether mean overall housing condition ratings differed by quadrant. F(3, 388) = 3.19, p = 0.0239 This confirms significant variation in housing condition by location, justifying spatially targeted intervention. 107 records with missing values were excluded from this analysis.

#1.10 Statistical Analysis: Regression Model A linear regression model was used to predict overall housing condition based on key component scores. Significant negative predictors included:

Gutters (β ≈ -2.1)

Foundation (β ≈ -1.3)

Wall Structure (β ≈ -1.1)

These components were the most influential in reducing overall housing quality.

#1.11 Statistical Analysis: Frequency Analysis A frequency count of condition ratings showed:

Gutters received the most “Severe” ratings (~260 instances)

Foundation, coating, and landscaping followed

Mechanical systems and hardscape had the fewest severe flags

These findings support prioritizing structural integrity and water drainage systems.

1.12 Statistical Analysis: Scatter Plot

A scatter plot of overall housing condition (y-axis) vs. gutters/foundation scores (x-axis) shows a visible negative trend:

ggplot(housing_data, aes(x = gutters_and_downspouts_assessment_score, 
                         y = rate_the_overall_home_condition)) +
  geom_jitter(width = 0.2, height = 0.2, alpha = 0.4) +
  geom_smooth(method = "lm", se = FALSE, color = "red") +
  labs(title = "Gutters vs. Overall Housing Condition",
       x = "Gutters Rating", y = "Overall Condition Score") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
## Warning: Removed 107 rows containing non-finite outside the scale range
## (`stat_smooth()`).
## Warning: Removed 107 rows containing missing values or values outside the scale range
## (`geom_point()`).

References

Alamo Area Metropolitan Planning Organization (AAMPO). (2021). 2050 Demographic Projections for San Antonio. Retrieved from https://aampo-mobility-2050-atginc.hub.arcgis.com

U.S. Census Bureau. (2022). American Community Survey (ACS) 5-Year Estimates. Retrieved via tidycensus R package. https://www.census.gov/programs-surveys/acs

Wickham, H. et al. (2023). tidyverse: Easily Install and Load the Tidyverse. R package version 2.0.0. https://www.tidyverse.org

Firke, S. (2023). janitor: Simple Tools for Examining and Cleaning Dirty Data. R package version 2.2.1. https://cran.r-project.org/package=janitor

Pebesma, E. (2018). Simple Features for R: Standardized Support for Spatial Vector Data. R Journal, 10(1), 439–446. https://journal.r-project.org/archive/2018/RJ-2018-009/index.html

Bivand, R., & Rundel, C. (2023). sf: Simple Features for R. R package version 1.0.12. https://cran.r-project.org/package=sf