You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This week simply download [this zip file](spatial-autocorrelation.zip?raw=true) and unpack it a local folder, then follow the [instructions here](assignment-spatial-autocorrelation.md).
Copy file name to clipboardExpand all lines: labs/spatial-autocorrelation/assignment-spatial-autocorrelation.md
+38-37Lines changed: 38 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
-
#### GISC 422 T1 2021
1
+
#### GISC 422 T2 2023
2
2
# **Assignment 2** Spatial autocorrelation in R and/or GeoDa
3
3
This assignment walks you through applying spatial autocorrelation measures, specifically Moran's index of spatial autocorrelation in both its local and global forms.
4
4
5
-
These instructions show how these analyses can be performed in *R*, although many of you may prefer to complete the assignment using *GeoDa* which is installed on the lab machines and also free to download and install from [this website](http://geodacenter.github.io/download.html). Operation of *GeoDa* is relatively self-explanatory whereas performing these analyses in *R* using the `spdep` package is not, so you are on your own in *GeoDa*, but should find these instructions a useful overview of the methods helpful for either platform. If you work in *R* you'll find making the final report easier since you can use *R Markdown*.
5
+
These instructions show how these analyses can be performed in *R*, although many of you may prefer to complete the assignment using *GeoDa* which is freely downloadable and installable on any computer from [this website](http://geodacenter.github.io/download.html). Operation of *GeoDa* is relatively self-explanatory whereas performing these analyses in *R* using the `spdep` package is not, so you are on your own in *GeoDa*, but should find these instructions a useful overview of the methods helpful for either platform. If you work in *R* you'll find making the final report easier since you can use *R Markdown*.
6
6
7
7
## Required packages
8
8
We need a bunch of these, so load them all now.
@@ -14,12 +14,16 @@ library(tmap)
14
14
library(dplyr) # for manipulating datasets
15
15
```
16
16
17
-
And also, the package that provides the spatial autocorrelation methods we need
17
+
And also, the package that provides the spatial autocorrelation methods we need along with some helper packages
18
18
19
19
```{r}
20
20
library(spdep)
21
+
library(sp)
22
+
library(maptools)
21
23
```
22
24
25
+
There is a newer package [`sfdep`](https://sfdep.josiahparry.com/index.html) based on `spdep` which operates on `sf` data rather than older _R_-spatial formats but it still requires you to drop back to using `spdep` on occasion, so these instructions are still geared towards use of `spdep`.
26
+
23
27
## The data
24
28
OK... now we are ready to load the data for this lab. This is a super-set of the data we previously used for the point pattern analysis lab, which includes the TB data for the old Auckland City, but extended to a wider region, and also with the additional inclusion of contemporary ethnicity data from the 2006 Census.
tm_borders(col = 'gray', lwd = 0.5) # add borders to the polygons
48
-
map
49
-
```
50
-
51
-
Remember also that if we want an interactive web map, we can change the `tmap` mode to `"view"`
52
-
53
-
```{r}
54
-
tmap_mode("view")
55
-
map
56
-
```
57
-
58
-
For now, we probably don't need interactive web maps, so change back to `"plot"` mode and make sure everything is still good to go
59
-
60
-
```{r}
61
-
tmap_mode("plot")
62
-
map
51
+
tm_borders(col = 'gray', lwd = 0.5) + # add borders to the polygons
52
+
tm_legend(position = c("left", "top"))
63
53
```
64
54
65
55
## Back to spatial autocorrelation
66
-
The functions discussed in this section and the remainder of these instructions are provided by the `spdep` package. This is an older package, which can work with `sf` objects but with some difficulty, so it is easier to make a `sp` package compatible `SpatialPolygonsDataFrame` object from our data for some of the operations to follow. We'll call this `akp` and will use the original `ak` object where it is more convenient, but work with `akp` when needed.
56
+
The functions discussed in this section and the remainder of these instructions are provided by the `spdep` package. This is an older package, which can work with `sf` objects but with some difficulty, so it is easier to make a `sp` package compatible `SpatialPolygonsDataFrame` object from our data for some of the operations that follow. We'll call this `aksp` and will use the original `ak` object where it is more convenient, but work with `aksp` when needed.
67
57
68
58
```{r}
69
-
akp <- as_Spatial(ak)
59
+
aksp <- ak %>%
60
+
as("Spatial")
70
61
```
71
62
72
-
Since `akp` and `ak` are derived from the same underlying data and retain the same *order* of entries in their data tables, we shouldn't run into any problems.
63
+
Since `aksp` and `ak` are derived from the same underlying data and retain the same *order* of entries in their data tables, we shouldn't run into any problems.
73
64
74
65
The main reason for making this object is that the key functions of `spdep` require the construction of *neighbourhoods* for each polygon in the dataset, on which the autocorrelation calculations will be based. The most basic neighbourhood construction is based on adjacency and is generated using the `poly2nb()` function. This is how it works
75
66
76
67
```{r}
77
-
nb <- poly2nb(akp, row.names = ak$AU_NAME, queen = TRUE)
68
+
nb <- aksp %>%
69
+
poly2nb(row.names = ak$AU_NAME, queen = TRUE)
78
70
```
79
71
80
72
We can inspect what we just did, with the `summary()` function
@@ -88,28 +80,34 @@ We can see here that we made a neighbourhood object that has 1612 adjacency link
88
80
To get a better idea what is going on we can map these
89
81
90
82
```{r}
91
-
plot(akp, col = "lightgrey", lwd = 0.5, border = 'white')
At this point, you should experiment with the `poly2nb` function (what happens if you set `queen = FALSE`?).
96
92
97
93
### Other neighborhood construction methods
98
-
It is possible to construct neighbourhoods on other bases, such as for example, the k nearest neighbours approach. This is unfortunately where the `spdep` package shows its age, because doing so is fiddly. Here is how it works, just as an example, that you are welcome to explore further.
94
+
It is possible to construct neighbourhoods on other bases, such as for example, the _k_ nearest neighbours approach. This is unfortunately where the `spdep` package shows its age, because doing so is fiddly. Here is how it works, just as an example, that you are welcome to explore further.
99
95
100
96
```{r}
101
-
ak_k5 <- knearneigh(coordinates(akp), k = 5)
102
-
nb_k5 <- knn2nb(ak_k5)
103
-
plot(akp, col = "lightgrey", lwd = 0.5, border = 'white')
You can probably see here why I say that the `spdep` functions are a bit obscure to work with. Anyway, let's return to doing the analysis based on simple adjacency, as recorded in the `nb` object we made before.
@@ -120,7 +118,8 @@ Something to pay attention to from here forward is that many of the Moran's inde
120
118
Another quirk of the `spdep` package is that it requires the neighbourhood information in a particular format to work, and this is *not* the format that the various neighbourhood construction methods produce. To get the right format we must convert the neighbourhood information to a `listw` object
121
119
122
120
```{r}
123
-
wl <- nb2listw(nb, style = "W", zero.policy = T)
121
+
wl <- nb %>%
122
+
nb2listw(style = "W", zero.policy = TRUE)
124
123
summary(wl, zero.policy = T)
125
124
```
126
125
@@ -130,7 +129,8 @@ As you can see (and reassuringly!) this object has exactly the same characterist
130
129
After all that, the moment of truth is very simple. We can calculate the value of Moran's index. The permutation approach discussed in lectures is the most appropriate way to put some kind of statistical limits on the result for interpretive purposes. This is invoked by `moran.mc()`
0 commit comments