I will be examining the annualized frequency of riverine flooding events on the tract level in Arizona. Riverine flooding occurs when the water in rivers or creeks swells and overflows the banks, creating potentially hazardous conditions for the surrounding area. Riverine flooding occurs over time but is made worse when sudden torrential rain causes flash floods. These rain events are especially common during Arizona’s monsoon season from June to September. Arizona’s arid landscape of washes and gullies makes it a prime target of landslides, making these flooding events more dangerous. By better understanding the risks of riverine flooding, we can alleviate the negative outcomes for the surrounding environment and population.
## Loading in Libraries
library(tidyverse)
library(sf)
library(tmap)
library(wordcountaddin)
library(spdep)
library(kableExtra)
## Read in CSV File
dat <- read_csv("raw_data/NRI_Table_CensusTracts_Arizona.csv")
## Select the Important Columns to be Included
dat <- dat |>
select(STATE, TRACTFIPS, RFLD_AFREQ)
## Rename the columns
dat <- dat |>
rename(Annualized_Frequency = RFLD_AFREQ, GEOID = TRACTFIPS)
## Just Get AZ Tracts for AZ From Tigris
tct_tiger_sf <- read_sf("raw_data/tct_tiger_sf.gpkg")
## Select the Important Columns to be Included for the Spatial Data Layer
tct_tiger_sf <- tct_tiger_sf |>
select(GEOID)
## Complete Table Join
az_tct_risk_sp <- left_join(tct_tiger_sf,
dat,
by = "GEOID")
My data sources were from the National Risk Index where I imported the census tract data for Arizona, and I also brought in a spatial data layer by downloading AZ tract level data from Tigris. I wrangled my data so I could specifically work with tracts in Arizona and my variable of interest, annualized frequency of riverine flooding by event days per year. Throughout the data wrangling process, I also selected the rows with data specifically for the annualized frequency of riverine flooding in Arizona and renamed these rows, so that I could better organize my data. I then joined my National Risk Index layer with my spatial data layer by the GeoID, so that I would only have to work with one table rather than two.
## Calculate Mean Annualized Frequency
mean <- mean(az_tct_risk_sp$Annualized_Frequency)
## Calculate Minimum Annualized Frequency
min <- min(az_tct_risk_sp$Annualized_Frequency)
## Calculate Maximum Annualized Frequency
max <- max(az_tct_risk_sp$Annualized_Frequency)
## Calculate Number of Observations
obs <- nrow(az_tct_risk_sp)
## Plot Histogram
ggplot(data = az_tct_risk_sp,
aes(Annualized_Frequency)) +
geom_histogram(binwidth = 1,
fill = "lightblue",
col = "grey20") +
xlab("Annualized Frequency of Riverine Flooding Event Days per Year in AZ")
The variable of interest, annualized frequency, helps to understand where the tracts in Arizona with the highest and lowest annual rates of riverine flooding are. This variable is calculated by taking the recorded number of event days over the period of record. Of the 1765 tracts in Arizona that I am observing, the largest annualized frequency of riverine flooding event days was 12.6666667, the smallest annualized frequency was 0 , the average annualized frequency was 4.1362134. Around 800 of the tracts experienced an annualized frequency of between 0-1.25 riverine flooding event days, but a little less than 500 had an annualized frequency between 6-7.5 events. It is difficult to see a general trend on the histogram as there are a significant tracts with small values as well as moderate annualized frequency.
## Make copy
az_af_org <- az_tct_risk_sp
## Remove NAs
az_tct_risk_sp <- az_tct_risk_sp |>
filter(!is.na(Annualized_Frequency))
## Create Queen case neighbors
az_queen <- poly2nb(az_tct_risk_sp,
queen = TRUE)
## First, convert our neighbors to weight matrix
az_q_weights <- nb2listw(az_queen,
style = "B",
zero.policy = TRUE)
## Moran's I
az_af_tct_moran <- moran.test(az_tct_risk_sp$Annualized_Frequency,
az_q_weights,
zero.policy = TRUE,
randomisation = TRUE)
## MORAN'S I VALUE
moran_i_value <- az_af_tct_moran$estimate[1]
## P-Value for MORAN'S I
moran_p_value <- az_af_tct_moran$p.value
## LISA Map
az_af_lisa <- localmoran(az_tct_risk_sp$Annualized_Frequency,# Variable we're analyzing
listw = az_q_weights, # Weights object
alternative = "two.sided", # Clustering or Dispersion
zero.policy = TRUE) |> # Best to keep TRUE for LISA
as_tibble() |> # Better object type
mutate(across(everything(), as.vector)) # Remove junk from localmoran output
## Add values required for LISA category
az_af_lisa <- az_af_lisa |>
mutate(SCVAR = scale(az_tct_risk_sp$Annualized_Frequency) |> as.vector(),
LAGVAR = lag.listw(az_q_weights, scale(az_tct_risk_sp$Annualized_Frequency)),
LISACAT = case_when(SCVAR >= 0 & LAGVAR >= 0 & `Pr(z != E(Ii))` <= 0.05 ~ 1,
SCVAR <= 0 & LAGVAR <= 0 & `Pr(z != E(Ii))` <= 0.05 ~ 2,
SCVAR >= 0 & LAGVAR <= 0 & `Pr(z != E(Ii))` <= 0.05 ~ 3,
SCVAR <= 0 & LAGVAR >= 0 & `Pr(z != E(Ii))` <= 0.05 ~ 4,
`Pr(z != E(Ii))` > 0.05 ~ 5))
## This simply adds a label based on the values
az_af_lisa <- az_af_lisa |>
mutate(CATNAME = case_when(LISACAT == 1 ~ "HH",
LISACAT == 2 ~ "LL",
LISACAT == 3 ~ "HL",
LISACAT == 4 ~ "LH",
LISACAT == 5 ~ "Not Significant"))
## Quick SUMMARY of LISA output
lisa_summary <- table(az_af_lisa$CATNAME)
## Add LISA category column to the spatial data for mapping!
az_tct_risk_sp <- az_tct_risk_sp |>
mutate(LISACAT = az_af_lisa$LISACAT,
CATNAME = az_af_lisa$CATNAME)
## Choropleth Map
az_af_tmap <-
tm_shape(az_af_org) +
tmap_mode("view") +
tm_polygons(col = "grey50") +
tm_shape(az_tct_risk_sp) +
tm_polygons("Annualized_Frequency",
title = "Annualized_Frequency (Days per Year)",
style = "jenks",
palette = "Blues",
colorNA = "white",
border.col = "black",
border.alpha = 0.25,
legend.hist = TRUE) +
tm_layout(frame = FALSE,
legend.outside = TRUE)
## LISA map
lisa_tmap <-
tm_shape(az_af_org) +
tmap_mode("view") +
tm_polygons(col = "grey50") +
tm_shape(az_tct_risk_sp) +
tm_polygons("LISACAT",
title = "LISA Category",
breaks = c(1, 2, 3, 4, 5, 6),
palette = c("red",
"blue",
"lightpink",
"skyblue",
"grey90"),
colorNA = "white",
labels = c("High-High",
"Low-Low",
"High-Low",
"Low-High",
"Not significant"),
border.col = "black",
border.alpha = 0.25) +
tm_layout(frame = FALSE,
legend.outside = TRUE)
## Map Them Together
tmap_arrange(az_af_tmap,
lisa_tmap,
ncol = 1,
nrow = 2)