::p_load(sf, tmap, tidyverse, maptools, raster, spatstat, tmap, funModeling) pacman
Take-home Exercise 1
1.0 Introduction
This analysis aims to take a look at all the functional and non-functional water points in Osun State, Nigeria. By looking at the location of the functional and non-functional water points, we will be able to determine which clusters require immediate rehabilitation and whether these clusters are statistically significant. The analysis will comprise of three parts: Exploratory analysis, Second order spatial analysis and Spatial Correlation Analysis among the functional and non-functional water points.
2.0 Load all the relevant packages
3.0 Load the Geospatial data from Humanitarian Data Exchange
Data Needed:
Dataset | Source |
---|---|
WPdx+ (Aspatial) | https://data.waterpointdata.org/dataset/Water-Point-Data-Exchange-Plus-WPdx-/eqje-vguj/data |
Humanitarian Data Exchange (Geospatial) | https://data.humdata.org/ |
We filter out everything else that is unnecessary outside of Osun
<- st_read(dsn = "data/geospatial",
NGA_wp_geo layer = "nga_admbnda_adm2_osgof_20190417") %>% filter(ADM1_EN == "Osun") %>% st_transform(crs=26392)
Reading layer `nga_admbnda_adm2_osgof_20190417' from data source
`D:\Documents\IS415-GAA-WY\take-home-ex\take-home-ex01\data\geospatial'
using driver `ESRI Shapefile'
Simple feature collection with 774 features and 16 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 2.668534 ymin: 4.273007 xmax: 14.67882 ymax: 13.89442
Geodetic CRS: WGS 84
4.0 Get information from Nigeria -> OSUN state only
<- read_csv("data/aspatial/nga_wp.csv") %>%
nga_wp_as filter(`#clean_country_name` == "Nigeria", `#clean_adm1` == "Osun")
4.1 Check for duplicated rows
$ADM2_EN[duplicated(NGA_wp_geo$ADM2_EN)==TRUE] NGA_wp_geo
character(0)
4.2 Convert water point data into sf point features
We need to convert the aspatial data into an sf dataframe
Below function, we will create sfc object from existing wkt column
$Geometry = st_as_sfc(nga_wp_as$`New Georeferenced Column`)
nga_wp_as nga_wp_as
# A tibble: 5,745 × 75
row_id `#source` #lat_…¹ #lon_…² #repo…³ #stat…⁴ #wate…⁵ #wate…⁶ #wate…⁷
<dbl> <chr> <dbl> <dbl> <chr> <chr> <chr> <chr> <chr>
1 225950 Federal Minis… 7.43 4.26 05/05/… Yes Boreho… Well Hand P…
2 225524 Federal Minis… 7.78 4.56 04/22/… Yes Protec… Well Hand P…
3 197014 Federal Minis… 7.49 4.53 04/30/… Yes Boreho… Well Mechan…
4 225173 Federal Minis… 7.93 4.73 05/02/… Yes Boreho… Well Hand P…
5 225843 Federal Minis… 7.74 4.44 05/08/… Yes Boreho… Well Hand P…
6 235508 Federal Minis… 7.15 4.64 04/27/… Yes Protec… Well Hand P…
7 197708 Federal Minis… 7.87 4.72 05/13/… Yes Boreho… Well Mechan…
8 195041 Federal Minis… 7.73 4.45 06/17/… Yes Protec… Spring <NA>
9 225222 Federal Minis… 7.81 4.15 05/14/… Yes Protec… Spring Mechan…
10 460770 GRID3 7.4 4.33 06/13/… Unknown Boreho… Well <NA>
# … with 5,735 more rows, 66 more variables: `#water_tech_category` <chr>,
# `#facility_type` <chr>, `#clean_country_name` <chr>, `#clean_adm1` <chr>,
# `#clean_adm2` <chr>, `#clean_adm3` <chr>, `#clean_adm4` <chr>,
# `#install_year` <dbl>, `#installer` <chr>, `#rehab_year` <lgl>,
# `#rehabilitator` <lgl>, `#management_clean` <chr>, `#status_clean` <chr>,
# `#pay` <chr>, `#fecal_coliform_presence` <chr>,
# `#fecal_coliform_value` <dbl>, `#subjective_quality` <chr>, …
4.3 Convert into table into sf object using the original wgs 84 coordinate system
<- st_sf(nga_wp_as, crs=4326) wp_sf
This function will convert it into Nigeria’s projected coordinate system
<- wp_sf %>%
wp_sf st_transform(crs = 26392)
5.0 Data Wrangling and Plotting of Water Point Data
Considering that we are mapping out the functional and non-functional water points, we will check the number of status clean and non status clean.
freq(data = wp_sf,
input = '#status_clean')
#status_clean frequency percentage cumulative_perc
1 Functional 2406 41.88 41.88
2 Non-Functional 2086 36.31 78.19
3 <NA> 748 13.02 91.21
4 Functional, needs repair 259 4.51 95.72
5 Non-Functional, dry 159 2.77 98.49
6 Functional, not in use 64 1.11 99.60
7 Abandoned/Decommissioned 15 0.26 99.86
8 Functional but not in use 8 0.14 100.00
5.1 Rename column name from #status clean to status_clean and replace na with ‘unknown’ tag
Need to prepend dplyr because raster has a similar function
<- wp_sf %>%
wp_sf_nga rename(status_clean = '#status_clean') %>%
rename(clean_adm2 = '#clean_adm2') %>%
::select(status_clean, clean_adm2) %>%
dplyrmutate(status_clean = replace_na(
"unknown")) status_clean,
5.2 Extract functional and non-functional water points
<- wp_sf_nga %>%
wp_functional filter(status_clean %in%
c("Functional",
"Functional but not in use",
"Functional but needs repair"))
<- wp_sf_nga %>%
wp_nonfunctional filter(status_clean %in%
c("Abandoned/Decommissioned",
"Abandoned",
"Non-Functional due to dry season",
"Non-Functional",
"Non functional due to dry season"))
<- wp_sf_nga %>%
wp_unknown filter(status_clean == "unknown")
5.3 Remove all unused or unneeded columns:
<- NGA_wp_geo %>%
NGA_wp_geo ::select(c(3:4, 8:9, )) dplyr
5.4 Performing Point-in-Polygon count
<- NGA_wp_geo %>%
NGA_wp_count mutate(`total_wp` = lengths(
st_intersects(NGA_wp_geo, wp_sf_nga))) %>%
mutate(`wp_functional` = lengths(
st_intersects(NGA_wp_geo, wp_functional))) %>%
mutate(`wp_nonfunctional` = lengths(
st_intersects(NGA_wp_geo, wp_nonfunctional))) %>%
mutate(`wp_unknown` = lengths(
st_intersects(NGA_wp_geo, wp_unknown)))
6.0 Deriving the Proportion of Functional to Non-Functional Water points
The visualization would be more effective as percentage would give a better story as to how many functional water points there are compared to non-functional and vice-versa. This can also be used as an anchor for our comparison later with our KDE maps and second-order spatial analysis.
<- NGA_wp_count %>%
NGA_wp_count mutate(pct_functional = wp_functional/total_wp) %>%
mutate(pct_nonfunctional = wp_nonfunctional/total_wp)
tm_shape(NGA_wp_count) +
tm_fill("pct_functional",
n = 10,
style = "equal",
palette = "Blues",
legend.hist = TRUE) +
tm_borders(lwd = 0.1,
alpha = 1) +
tm_layout(main.title = "Rate map of functional water point by LGAs in Osun",
legend.outside = TRUE)
tm_shape(NGA_wp_count) +
tm_fill("pct_nonfunctional",
n = 10,
style = "equal",
palette = "Blues",
legend.hist = TRUE) +
tm_borders(lwd = 0.1,
alpha = 1) +
tm_layout(main.title = "Rate map of non-functional water point by LGAs in Osun",
legend.outside = TRUE)
6.1 Mapping all the water points on the map
tmap_mode('view') +
tm_shape(wp_sf_nga) +
tm_dots(col="status_clean",
size=0.01,
border.lwd=0.5) +
tm_view(set.zoom.limits = c(9,16))
7.0 Deriving the Kernel Density Maps of Functional/Non-Functional Water points
Convert sf dataframes into spatial class
<- as_Spatial(wp_functional)
wp_func_spatial_class <- as_Spatial(wp_nonfunctional)
wp_nfunc_spatial_class <- as_Spatial(NGA_wp_geo) wp_osun
7.1 Check the type to convert to
wp_func_spatial_class
class : SpatialPointsDataFrame
features : 2414
extent : 177285.9, 290751, 343128.1, 450859.7 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=4 +lon_0=8.5 +k=0.99975 +x_0=670553.98 +y_0=0 +a=6378249.145 +rf=293.465 +towgs84=-92,-93,122,0,0,0,0 +units=m +no_defs
variables : 2
names : status_clean, clean_adm2
min values : Functional, Aiyedade
max values : Functional but not in use, Osogbo
wp_nfunc_spatial_class
class : SpatialPointsDataFrame
features : 2101
extent : 180539, 290546.5, 340054.1, 450780.1 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=4 +lon_0=8.5 +k=0.99975 +x_0=670553.98 +y_0=0 +a=6378249.145 +rf=293.465 +towgs84=-92,-93,122,0,0,0,0 +units=m +no_defs
variables : 2
names : status_clean, clean_adm2
min values : Abandoned/Decommissioned, Aiyedade
max values : Non-Functional, Osogbo
wp_osun
class : SpatialPolygonsDataFrame
features : 30
extent : 176503.2, 291043.8, 331434.7, 454520.1 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=4 +lon_0=8.5 +k=0.99975 +x_0=670553.98 +y_0=0 +a=6378249.145 +rf=293.465 +towgs84=-92,-93,122,0,0,0,0 +units=m +no_defs
variables : 4
names : ADM2_EN, ADM2_PCODE, ADM1_EN, ADM1_PCODE
min values : Aiyedade, NG030001, Osun, NG030
max values : Osogbo, NG030030, Osun, NG030
7.2 Convert into generic sp format
<- as(wp_func_spatial_class, "SpatialPoints")
wp_func_sp <- as(wp_nfunc_spatial_class, "SpatialPoints")
wp_nfunc_sp <- as(wp_osun, "SpatialPolygons") wp_osun_sp
7.3 Convert the generic format into spatstat’s ppp format
<- as(wp_func_sp, "ppp")
wp_func_ppp <- as(wp_nfunc_sp, "ppp") wp_nfunc_ppp
7.4 Plot Planar Point
plot(wp_func_sp)
7.5 Summary Statistics
summary(wp_func_ppp)
Planar point pattern: 2414 points
Average intensity 1.974841e-07 points per square unit
Coordinates are given to 2 decimal places
i.e. rounded to the nearest multiple of 0.01 units
Window: rectangle = [177285.9, 290750.96] x [343128.1, 450859.7] units
(113500 x 107700 units)
Window area = 12223800000 square units
summary(wp_nfunc_ppp)
Planar point pattern: 2101 points
Average intensity 1.724859e-07 points per square unit
Coordinates are given to 2 decimal places
i.e. rounded to the nearest multiple of 0.01 units
Window: rectangle = [180538.96, 290546.54] x [340054.1, 450780.1] units
(110000 x 110700 units)
Window area = 12180700000 square units
Check for duplicated points
any(duplicated(wp_func_ppp))
[1] FALSE
any(duplicated(wp_nfunc_ppp))
[1] FALSE
No duplicate points identified.
7.6 Creating the Osun Confines using owin object
<- as(wp_osun_sp, "owin") osun_owin
plot(osun_owin)
7.7 Combine Functional and Non-Functional Point Events Object and Owin Object
= wp_func_ppp[osun_owin]
wp_func_ppp_comb = wp_nfunc_ppp[osun_owin] wp_nfunc_ppp_comb
summary(wp_func_ppp_comb)
Planar point pattern: 2316 points
Average intensity 2.681826e-07 points per square unit
Coordinates are given to 2 decimal places
i.e. rounded to the nearest multiple of 0.01 units
Window: polygonal boundary
30 separate polygons (no holes)
vertices area relative.area
polygon 1 204 766084000 0.08870
polygon 2 81 304399000 0.03520
polygon 3 97 465688000 0.05390
polygon 4 124 373051000 0.04320
polygon 5 60 149473000 0.01730
polygon 6 84 144820000 0.01680
polygon 7 50 102243000 0.01180
polygon 8 72 216002000 0.02500
polygon 9 112 269897000 0.03130
polygon 10 125 365142000 0.04230
polygon 11 83 111191000 0.01290
polygon 12 126 192557000 0.02230
polygon 13 219 904397000 0.10500
polygon 14 174 741131000 0.08580
polygon 15 81 138742000 0.01610
polygon 16 65 119452000 0.01380
polygon 17 90 280205000 0.03240
polygon 18 69 69814600 0.00808
polygon 19 69 42727500 0.00495
polygon 20 49 30458800 0.00353
polygon 21 62 263505000 0.03050
polygon 22 93 438930000 0.05080
polygon 23 87 274127000 0.03170
polygon 24 105 509979000 0.05910
polygon 25 98 292058000 0.03380
polygon 26 64 327765000 0.03800
polygon 27 133 108945000 0.01260
polygon 28 122 462169000 0.05350
polygon 29 94 109715000 0.01270
polygon 30 95 61239800 0.00709
enclosing rectangle: [176503.22, 291043.82] x [331434.7, 454520.1] units
(114500 x 123100 units)
Window area = 8635910000 square units
Fraction of frame area: 0.613
8.0 Plot functional and non-functional points
par(mfrow=c(1,2))
plot(wp_func_ppp_comb)
plot(wp_nfunc_ppp_comb)
8.1 Deriving the Kernel Density Map
<- density(wp_func_ppp_comb,
kde_wp_func_map sigma=bw.diggle,
edge=TRUE,
kernel="gaussian")
<- density(wp_nfunc_ppp_comb,
kde_wp_nfunc_map sigma=bw.diggle,
edge=TRUE,
kernel="gaussian")
par(mfrow=c(1,2))
plot(kde_wp_func_map)
plot(kde_wp_nfunc_map)
8.2 Rescale to KM
<- rescale(wp_func_ppp_comb, 1000, "km")
wp_func_ppp_comb.km <- rescale(wp_nfunc_ppp_comb, 1000, "km") wp_nfunc_ppp_comb.km
8.3 Rerun Density for both functional and non-functional water point:
<- density(wp_func_ppp_comb.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
kde_wp_func_map.bw
<- density(wp_nfunc_ppp_comb.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian") kde_wp_nfunc_map.bw
par(mfrow=c(1,2))
plot(kde_wp_func_map.bw)
plot(kde_wp_nfunc_map.bw)
8.4 Computing Kernel Density Estimation using automatic bandwidth selection method
From our hands-on exercise, we were given the choice of either using bw.ppl or bw.diggle or adaptive kernel density estimatation method. We were told that bw.ppl is recommended specifically if the patterns are comprised of mostly tight clusters and well-distributed, and adaptive density are used if the data points are sparse. From my observation during the plotting of the water points, there appears to be a few tight clusters all throughout Osun and appear to be well-distributed. In lieu of that observation, I will be going with bw.ppl algorithm to determine the fixed bandwidth.
So, I will go with bw.ppl in this case.
<- density(wp_func_ppp_comb.km, sigma=bw.ppl, edge=TRUE, kernel="gaussian")
kde_wp_func_map.ppl <- density(wp_nfunc_ppp_comb.km, sigma=bw.ppl, edge=TRUE, kernel="gaussian") kde_wp_nfunc_map.ppl
8.5 KDE Functional Points
plot(kde_wp_func_map.ppl, main = "bw.ppl")
8.6 KDE Non-Functional Points
plot(kde_wp_nfunc_map.ppl, main = "bw.ppl")
8.7 Convert KDE output into Grid object
<- as.SpatialGridDataFrame.im(kde_wp_func_map.ppl)
gridded_kde_wp_func_ppl <- as.SpatialGridDataFrame.im(kde_wp_nfunc_map.ppl)
gridded_kde_wp_nfunc_ppl spplot(gridded_kde_wp_func_ppl)
spplot(gridded_kde_wp_nfunc_ppl)
8.8 Rasterise Layer so it can be mapped on tmap
<- raster(gridded_kde_wp_func_ppl)
kde_wp_func_map_ppl_raster <- raster(gridded_kde_wp_nfunc_ppl) kde_wp_nfunc_map_ppl_raster
Check the RASTER
kde_wp_func_map_ppl_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 0.8948485, 0.9616045 (x, y)
extent : 176.5032, 291.0438, 331.4347, 454.5201 (xmin, xmax, ymin, ymax)
crs : NA
source : memory
names : v
values : -9.008439e-16, 15.26599 (min, max)
kde_wp_nfunc_map_ppl_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 0.8948485, 0.9616045 (x, y)
extent : 176.5032, 291.0438, 331.4347, 454.5201 (xmin, xmax, ymin, ymax)
crs : NA
source : memory
names : v
values : -4.018365e-16, 9.797343 (min, max)
Assign Nigeria Projection System (ESG: 26392)
projection(kde_wp_func_map_ppl_raster) <- CRS("+init=EPSG:26392 +units=km")
projection(kde_wp_nfunc_map_ppl_raster) <- CRS("+init=EPSG:26392 +units=km")
8.9 Visualize functional/non-functional water point map output in TMAP:
tm_basemap("OpenStreetMap") +
tmap_mode('plot') +
tm_shape(kde_wp_func_map_ppl_raster) +
tm_raster("v") +
tm_layout(legend.position = c("right", "bottom"),
frame = FALSE,
main.title="Functional Water Points",
main.title.position = "center",
main.title.size = 1)+
tm_view(set.zoom.limits = c(12,16))
tm_basemap("OpenStreetMap") +
tmap_mode('plot') +
tm_shape(kde_wp_nfunc_map_ppl_raster) +
tm_raster("v") +
tm_layout(legend.position = c("right", "bottom"),
frame = FALSE,
main.title="Non-Functional Water Points",
main.title.position = "center",
main.title.size = 1)+
tm_view(set.zoom.limits = c(12,16))
10.0 Describe the spatial patterns revealed by the kernel density maps.
From the maps above, we can tell at first glance that the functional water points and non-functional water points are concentrated at a few points. Another interesting point of note are that most of the water point areas, regardless of functioning/non-functioning are situated on the northern side of the map, with one large cluster of non-functional water points at the center of Osun.
The last observation is there are more clusters of non-functioning water points compared to functioning ones.
11.0 Highlight the advantage of kernel density map over point map.
We will define the point plot of both the functional and non-functional water points to compare visualization.
tmap_mode('view') +
tm_shape(wp_functional) +
tm_dots(col="status_clean",
size=0.01,
border.lwd=0.5) +
tm_view(set.zoom.limits = c(9,16))
tmap_mode('view') +
tm_shape(NGA_wp_geo) +
tm_polygons() +
tm_shape(wp_nonfunctional) +
tm_dots(col="status_clean",
size=0.01,
border.lwd=0.5) +
tm_view(set.zoom.limits = c(9,16))
tmap_mode('view') +
tm_shape(NGA_wp_geo) +
tm_borders() +
tm_shape(wp_sf_nga) +
tm_dots(col="status_clean",
size=0.01,
border.lwd=0.5) +
tm_view(set.zoom.limits = c(9,16))
From one look at the point map, it’s not immediately obvious where the clusters are as the water points are generally well-distributed across Osun. It is only after we look at the kernel density map that it becomes obvious and clearer that the functional water points are mostly concentrated on the north west of Osun, with small clusters of non-functional water points scattered throughout. This also supports our earlier exploratory analysis where it’s revealed that Ede North and Ejigbo has a higher proportion of functioning water points, and central areas like Ife Central and Ifelodon are lacking functional ones.
From this map, we can prioritise areas that would need to be fixed, and also to investigate why certain LGA’s have a higher cluster/proportion of non-functioning water points compared to others.
11.0 Second Order Spatial Point Patterns Analysis
Now that we have completed our spatial data analysis, it’s time we look at some of the areas where there are particularly high clusters of functioning and non-functioning water points and determine whether their clusters are statistically significant or not.
For this, I have chosen two states each as identified in the kernel density map for areas with high cluster of functioning and non-functioning water points. We will also use the G function across the entire state of Osun to confirm that all (both functioning and non-functioning) water point’s cluster are statistically significant.
Functioning:
- Ejigbo
- Ede North
Non-Functioning:
- Ifelodun
- Ife Central
Hypothesis:
H0: The distribution of the water points are random and evenly spaced
H1: The distribution of the water points are not randomly distributed and clustered
Confidence Level: 95%; Significance level: 5%/0.05
12.0 Create our Owin Object for all the LGAs
= wp_osun[wp_osun$ADM2_EN == 'Ejigbo',] %>%
ejigbo_area as('SpatialPolygons') %>%
as('owin')
= wp_osun[wp_osun$ADM2_EN == 'Ede North',]%>%
ede_north_area as('SpatialPolygons') %>%
as('owin')
= wp_osun[wp_osun$ADM2_EN == 'Ifelodun',]%>%
ifelodun_area as('SpatialPolygons') %>%
as('owin')
= wp_osun[wp_osun$ADM2_EN == 'Ife Central',]%>%
ife_central_area as('SpatialPolygons') %>%
as('owin')
par(mfrow=c(2,2))
plot(ejigbo_area, main="Ejigbo")
plot(ede_north_area, main="Ede North")
plot(ifelodun_area, main="Ifelodun")
plot(ife_central_area, main="Ife Central")
12.1 Extract the relevant areas for the functioning/non-functioning water points
#Functioning Water points
= wp_func_ppp[ejigbo_area]
wp_func_ejigbo_ppp = wp_func_ppp[ede_north_area]
wp_func_ede_north_ppp
#Non-functioning
= wp_nfunc_ppp[ifelodun_area]
wp_nfunc_ifelodun_ppp = wp_nfunc_ppp[ife_central_area] wp_nfunc_ife_central_ppp
12.2 Rescale them
= rescale(wp_func_ejigbo_ppp, 1000, "km")
wp_func_ejigbo_ppp.km = rescale(wp_func_ede_north_ppp, 1000, "km")
wp_func_ede_north_ppp.km = rescale(wp_nfunc_ifelodun_ppp, 1000, "km")
wp_nfunc_ifelodun_ppp.km = rescale(wp_nfunc_ife_central_ppp, 1000, "km") wp_nfunc_ife_central_ppp.km
12.3 Functioning Water points
par(mfrow=c(1,2))
plot(wp_func_ejigbo_ppp.km, main="Ejigbo")
plot(wp_func_ede_north_ppp.km, main="Ede North")
12.4 Non-functioning Water point
par(mfrow=c(1,2))
plot(wp_nfunc_ifelodun_ppp.km, main="Ifelodun")
plot(wp_nfunc_ife_central_ppp.km, main="Ife Central")
13.0 Using the G Function for Functioning Water Points
We will use the G Function, Gest(), to measure the distribution of the spatial point patterns, in this case, our water points. If the lines are outside of the envelop, we can say that it’s statistically significant with 95% confidence.
13.1 Ejigbo Study Area
= Gest(wp_func_ejigbo_ppp.km, correction="best")
G_ejigbo plot(G_ejigbo)
13.2 Complete Spatial Randomness Test
<- envelope(wp_func_ejigbo_ppp.km, Gest, nsim = 39) G_ejigbo.csr
Generating 39 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39.
Done.
plot(G_ejigbo.csr)
We can say that the distribution of functional water points are clustered as they increase rapidly within a short distance of 0.5km and that it’s statistically significant as it lies outside the envelope.
13.3 Ede North Study Area:
= Gest(wp_func_ede_north_ppp.km, correction="best")
G_ede_north plot(G_ede_north)
13.4 Complete Spatial Randomness Test
<- envelope(wp_func_ede_north_ppp.km, Gest, nsim = 39) G_ede_north.csr
Generating 39 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39.
Done.
plot(G_ede_north.csr)
Similar results to the Ede North. The functioning water points are all clustered and statistically significant. We reject the null hypothesis that they are randomly distributed and evenly spaced.
Overall results seems to indicate that functioning water points are generally clustered around certain places. This indicates that there might be practical/geographical reasons why the functioning water points are placed at where they are.
14.0 Using the G Function for Non-Functioning Water Points
14.1 Ifelodun Study Area
= Gest(wp_nfunc_ifelodun_ppp.km, correction="best")
G_ifelodun plot(G_ifelodun)
14.2 Complete Spatial Randomness Test
<- envelope(wp_nfunc_ifelodun_ppp.km, Gest, nsim = 39) G_ifelodun.csr
Generating 39 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39.
Done.
plot(G_ifelodun.csr)
14.3 Ife Central Study Area
= Gest(wp_nfunc_ife_central_ppp.km, correction="best")
G_ife_central_area plot(G_ife_central_area)
14.4 Complete Spatial Randomness Test
<- envelope(wp_nfunc_ife_central_ppp.km, Gest, nsim = 39) G_ife_central_area.csr
Generating 39 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39.
Done.
plot(G_ife_central_area.csr)
From the above results, we can say that the distribution of non-functioning water points are also clustered and not randomly distributed. Which means there might be external reasons why non-functioning water points are clustered at these areas. We reject the null hypothesis that they are randomly distributed and evenly spaced.
15.0 Running on the entire Osun State by including the Functioning and Non-functioning Water Points:
15.1 Creating the PPP and Owin object
<- as_Spatial(wp_sf_nga) %>%
wp_ppp as("SpatialPoints") %>%
as("ppp")
= wp_ppp[osun_owin]
wp_ppp = rescale(wp_ppp, 1000, "km") wp_ppp.km
We’ll now perform the G Function across the entire Osun state to confirm our hypothesis that the water points are clustered in general.
= Gest(wp_ppp.km, correction="best") G_osun_state
15.2 Plot
plot(G_osun_state)
<- envelope(wp_ppp.km, Gest, nsim = 39) G_osun_state.csr
Generating 39 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39.
Done.
15.3 Plot the Envelop
plot(G_osun_state.csr)
15.4 G-Function on Functioning Water Points
<- envelope(wp_func_ppp_comb.km, Gest, nsim = 39) G_osun_state_func.csr
Generating 39 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39.
Done.
plot(G_osun_state_func.csr)
15.5 G-Function on Non-Functioning Water Points
<- envelope(wp_nfunc_ppp_comb.km, Gest, nsim = 39) G_osun_state_nfunc.csr
Generating 39 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39.
Done.
plot(G_osun_state_nfunc.csr)
From the above analysis we can say for certain that all the water points in Osun state are clustered and statistically significant as we reject the null hypothesis that they are randomly and evenly distributed. Again, the reason why this could be the case is the same as above, in that there could potentially be practical/geographical reasons why the water points are placed there.
Reasons could be there are natural water sources such as rivers, quarries and reservoirs at these areas or these areas are heavily populated with people, and the water points are built close to residential areas.
16.0 Spatial Correlation Analysis
To confirm whether the spatial distribution of functional and non-functional water points are independent, we will be using the L-Function for correlation analysis. We will applying this over the entire Osun state with both functional and non-functional water points combined.
H0: The functional and non-functional water points are distributed randomly and spatially independent
H1: The functional and non-functional water points are distributed non-random and spatially dependent.
Confidence Level: 95%
Null hypothesis will be rejected.
17.0 Run the L-Function on Osun State:
We’ll now perform the L Function across the entire Osun state using the PPP and owin object we’ve created earlier.
= Lest(wp_ppp.km, correction="Ripley")
L_osun_state plot(L_osun_state, . -r ~ r,
ylab= "L(d)-r", xlab = "d(km)")
17.1 Complete Spatial Randomness Test
<- envelope(wp_ppp.km, Lest, nsim = 39, rank = 1, glocal=TRUE) L_osun_state.csr
17.2 Plot the Envelop
plot(L_osun_state.csr, . - r ~ r, xlab="d(km)", ylab="L(d)-r")
From the combined functional and non-functional water points. We can say with statistical certainty that the functional and non-functional points are clustered close to each other, as from the graph the distance is so small that it can’t even be seen and are spatially dependent on each other. Therefore we reject the null hypothesis that the water points are distributed randomly and spatially independent from each other.
This finding ties in with the earlier cluster analysis using the G-Function that there might be practical/geographical reasons why they are spatially dependent and clustered in certain areas. Reasons can include having water points close to residential areas or close to natural water sources such as rivers, quarries or reservoirs.
Acknowledgement:
Thanks to Prof. Kam for the resources on his hands-on and in-class exercises that assisted in the completion of this take home exercise!
Referenced the Spatstat book for advice on which functions to use.