<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/an-introduction-to-spatial-econometrics-in-r/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://ignaciomsarmiento.github.io/2017/02/07/An-Introduction-to-Spatial-Econometrics-in-R.html"> Ignacio Sarmiento Barbieri</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>This tutorial was prepared for the Ninth Annual Midwest Graduate Student Summit on Applied Economics, Regional, and Urban Studies (AERUS) on April 23rd-24th, 2016 at the University of Illinois at Urbana Champaign.</p>
<p>This notes illustrate the usage of <code>R</code> for spatial econometric analysis. The theory is heavily borrowed from Anselin and Bera (1998) and Arbia (2014) and the practical aspect is an updated version of Anselin (2003), with some additions in visualizing spatial data on <code>R</code>.</p>
<h1>What’s R and why use it?</h1>
<p>R is a free, open-source, and object oriented language. Free and open-source means that anyone is free to use, redistribute and change the software in any way. Moreover, “R is a free software environment for statistical computing and graphics. It compiles and runs on a wide variety of UNIX platforms, Windows and MacOS.” (<a target="_blank" rel="nofollow" href="http://cran.r-project.org/">http://cran.r-project.org</a>)</p>
<p>There are lot of software out there to do data analysis that are prettier and seem easier than R, so why should I invest learning R? There are in my opinion at least three characteristics of R that make it worthwhile learning it. First of all, it is free. Many fancier looking software used today are quite expensive, but R is free and is going to be always free. R also is a language, which means that you don’t only get to use the functions that are build in the software but you can create your own (just to get an on the of the power of the R language you can take a look Professor <a target="_blank" rel="nofollow" href="http://cran.r-project.org/web/packages/quantreg/index.html">Koenker’s Quantile Regression</a> package). The last reason is that R is extremely well supported. If you have a question you just can <a target="_blank" rel="nofollow" href="http://www.google.com/">Google</a> it, post it to <a target="_blank" rel="nofollow" href="http://stackoverflow.com/">StackOverflow</a> or use <a target="_blank" rel="nofollow" href="http://www.r-bloggers.com/">R-blogger</a>. If you are not convinced yet, just can type “why use the R language”” in Google and I think the results will speak by themselves. All these characteristics plus the fact that researchers at the frontier of the profession use <code>R</code> as part of their research make <code>R</code> a great tool for spatial data analysis.</p>
<h1>Introduction to spatial analysis in R</h1>
<h2>Motivation for using spatial analysis</h2>
<p>Probably the most important argument for taking a spatial approach is that the independence assumption between observation is no longer valid. Attributes of observation <em>i</em> may influence the attributes of observation <em>j</em>.</p>
<p>To illustrate a very small set of what can be achieved in <code>R</code> for spatial analysis our running example will be examining violent crimes and foreclosures in the City of Chicago. The crime data as well as tracts shapefiles used here comes from <a target="_blank" rel="nofollow" href="https://data.cityofchicago.org/">Chicago Data Portal</a> while foreclosures data come from the <a target="_blank" rel="nofollow" href="https://www.huduser.gov/portal/datasets/NSP.html">U.S. Department of Housing and Urban Development (HUD)</a>, all of these are public available.</p>
<h2>R packages for spatial data analysis.</h2>
<p>In R, the fundamental unit of shareable code is the package. A package bundles together code, data, documentation, and tests, and is easy to share with others. As of April 2016, there were over 8,200 packages available on the Comprehensive R Archive Network, or CRAN, the public clearing house for R packages. This huge variety of packages is one of the reasons that R is so successful: the chances are that someone has already solved a problem that you’re working on, and you can benefit from their work by downloading their package. (Wickham (2015))</p>
<p>Today we’ll focus on three packages <code>maptools</code> (R. Bivand and Lewin-Koh (2016)), <code>spdep</code> (R. Bivand and Piras (2015), R. Bivand, Hauke, and Kossowski (2013)) and <code>leaflet</code> (Cheng and Xie (2015)) and use a fourth one, the <code>RColorBrewer</code> package (Neuwirth (2014)) to make our plots more attractive. To install the packages, we simple have to type</p>
<div>
<pre><code><span>install.packages</span><span>(</span><span>&quot;maptools&quot;</span><span>,</span><span> </span><span>dependencies</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span><span>
</span><span>install.packages</span><span>(</span><span>&quot;spdep&quot;</span><span>,</span><span> </span><span>dependencies</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span><span>
</span><span>install.packages</span><span>(</span><span>&quot;leaflet&quot;</span><span>,</span><span> </span><span>dependencies</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span><span>
</span><span>install.packages</span><span>(</span><span>&quot;RColorBrewer&quot;</span><span>,</span><span> </span><span>dependencies</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span><span>
</span></code></pre>
</div>
<p>The <code>maptools</code> package has the functions needed to read geographic data, in particular ESRI shapefiles. The <code>spdep</code> package on the other hand contains the functions that will use in the spatial data analysis. The <strong>dependencies</strong> option installs uninstalled packages which these packages depend on. To access the functions and data in the package we must first call it. The function to call a package is <code>library</code></p>
<div>
<pre><code><span>library</span><span>(</span><span>spdep</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## Loading required package: sp

## Loading required package: Matrix
</code></pre>
</div>
<div>
<pre><code><span>library</span><span>(</span><span>maptools</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## Checking rgeos availability: TRUE
</code></pre>
</div>
<p>Now that the packages are loaded we can read in our data.</p>
<h2>Reading and Mapping spatial data in R</h2>
<p>Spatial data comes in many “shapes” and “sizes”, the most common types of spatial data are:</p>
<ul>
<li><strong>Points</strong> are the most basic form of spatial data. Denotes a single point location, such as cities, a GPS reading or any other discrete object defined in space.</li>
<li><strong>Lines</strong> are a set of ordered points, connected by straight line segments</li>
<li><strong>Polygons</strong> denote an area, and can be thought as a sequence of connected points, where the first point is the same as the last</li>
<li><strong>Grid</strong> (Raster) are a collection of points or rectangular cells, organized in a regular lattice</li>
</ul>
<p>For more details, see R. S. Bivand, Pebesma, and Gomez-Rubio (2008). Today we’ll focus on <strong>Polygons</strong>. Spatial data usually comes in <code>shapefile</code>. This type of files stores non topological geometry and attribute information for the spatial features in a data set. Moreover, they don’t require a lot of disk space and are easy to read and write. (ESRI (1998))</p>
<p>First we have to download and save the files in our computer from our server at <a target="_blank" rel="nofollow" href="http://www.econ.uiuc.edu/~lab/workshop/foreclosures/">http://www.econ.uiuc.edu/~lab/workshop/foreclosures/</a>. I saved mine in my desktop. We’ve downloaded 3 files:</p>
<ul>
<li>Main file: foreclosures.shp</li>
<li>Index file: foreclosures.shx</li>
<li>dBASE table: foreclosures.dbf</li>
</ul>
<p>The main file describes a shape with a list of its vertices. In the index file, each record contains the offset of the corresponding main file record from the beginning of the main file. The dBASE table contains feature attributes with one record per feature. (ESRI (1998))</p>
<p>To read data from a polygon shapefile into <code>R</code> we use the function <code>readShapePoly</code> that will create a <code>SpatialPolygonsDataFrame</code> object. To learn more about the function, the command <code>?readShapePoly</code> will give you access to the help file.</p>
<p>But before reading in the shapefile we first set our working directory. R is always pointing to a directory on your computer, to find which one use <code>getwd()</code> (get working directory). To specify a working directory:</p>
<div>
<pre><code><span>setwd</span><span>(</span><span>'~/Desktop/foreclosures'</span><span>)</span><span>
</span></code></pre>
</div>
<p>On windows you may have to use <code>\</code>. The <strong>foreclosures</strong> folder contain the shapefiles that I downloaded before. Now we are ready to read in our shapefile.</p>
<div>
<pre><code><span>chi.poly</span><span> </span><span>&lt;-</span><span> </span><span>readShapePoly</span><span>(</span><span>'foreclosures.shp'</span><span>)</span><span>
</span></code></pre>
</div>
<p>the shapefile is now read and stored in an object called <code>chi.poly</code>. To check that it is a <code>SpatialPolygonsDataFrame</code> we can use the function <code>class</code></p>
<div>
<pre><code><span>class</span><span>(</span><span>chi.poly</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## [1] &quot;SpatialPolygonsDataFrame&quot;
## attr(,&quot;package&quot;)
## [1] &quot;sp&quot;
</code></pre>
</div>
<p>A <code>SpatialPolygonsDataFrame</code> objects brings together the spatial representations of the polygons with data. The identifying tags of the polygons in the slot are matched with the row names of the data frame to make sure that the correct data rows are associated with the correct spatial object. (R. S. Bivand, Pebesma, and Gomez-Rubio (2008))</p>
<p>This object has four “parts” or <code>slots</code>: the first one is the <em>data</em> slot that contains the variables that will be used for our analysis; the second one is the <em>polygon</em> slot and contains the “shape” information. The third slot, <em>bbox</em>, is the bounding box drawn around the boundaries and the fourth slot is the <em>proj4string</em> which contains the projections. To access the <em>data</em> slot we can use the <code>slot</code> function or the <code>@</code> symbol. For a compact look of the data slot we can use the <code>str</code> function:</p>
<div>
<pre><code><span>str</span><span>(</span><span>slot</span><span>(</span><span>chi.poly</span><span>,</span><span>&quot;data&quot;</span><span>))</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## 'data.frame':    897 obs. of  16 variables:
##  $ SP_ID     : Factor w/ 897 levels &quot;1&quot;,&quot;10&quot;,&quot;100&quot;,..: 1 112 223 334 445 556 667 778 887 2 ...
##  $ fips      : Factor w/ 897 levels &quot;17031010100&quot;,..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ est_fcs   : int  43 129 55 21 64 56 107 43 7 51 ...
##  $ est_mtgs  : int  904 2122 1151 574 1427 1241 1959 830 208 928 ...
##  $ est_fcs_rt: num  4.76 6.08 4.78 3.66 4.48 4.51 5.46 5.18 3.37 5.5 ...
##  $ res_addr  : int  2530 3947 3204 2306 5485 2994 3701 1694 443 1552 ...
##  $ est_90d_va: num  12.61 12.36 10.46 5.03 8.44 ...
##  $ bls_unemp : num  8.16 8.16 8.16 8.16 8.16 8.16 8.16 8.16 8.16 8.16 ...
##  $ county    : Factor w/ 1 level &quot;Cook County&quot;: 1 1 1 1 1 1 1 1 1 1 ...
##  $ fips_num  : num  1.7e+10 1.7e+10 1.7e+10 1.7e+10 1.7e+10 ...
##  $ totpop    : int  5391 10706 6649 5325 10944 7178 10799 5403 1089 3634 ...
##  $ tothu     : int  2557 3981 3281 2464 5843 3136 3875 1768 453 1555 ...
##  $ huage     : int  61 53 56 60 54 58 48 57 61 48 ...
##  $ oomedval  : int  169900 147000 119800 151500 143600 145900 153400 170500 215900 114700 ...
##  $ property  : num  646 914 478 509 641 612 678 332 147 351 ...
##  $ violent   : num  433 421 235 159 240 266 272 146 78 84 ...
##  - attr(*, &quot;data_types&quot;)= chr  &quot;C&quot; &quot;C&quot; &quot;N&quot; &quot;N&quot; ...
</code></pre>
</div>
<p>The first part is the <code>data.frame</code> part that contains the data for our analysis. We can see the variables contained in the data portion of the file including:</p>
<ul>
<li>est_fcs: estimated count of foreclosure starts from Jan. 2007 through June 2008</li>
<li>est_mtgs: estimated number of active mortgages from Jan. 2007 through June 2008</li>
<li>est_fcs_rt: number of foreclosure starts divided by number of mortgages times 100</li>
<li>bls_unemp: June 2008 place or county unemployment rate</li>
<li>totpop: total population from 2000 Census</li>
<li>violent: number of violent crimes reported between Jan. 2007 through December 2008</li>
<li>property: number of property crimes reported between Jan. 2007 through December 2008</li>
</ul>
<p>We can also get summary statistics of the variables of interest using the function summary. For example,</p>
<div>
<pre><code><span>summary</span><span>(</span><span>chi.poly</span><span>@</span><span>data</span><span>$</span><span>violent</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
##     0.0    49.0   103.0   169.3   226.0  1521.0
</code></pre>
</div>
<p>Here we accessed the data portion of the shapefile with the <code>@</code> sign and then the variable with the <code>$</code> sign. To see the other slots, we can proceed in the same fashion.</p>
<p>A nice feature of the class of spatial objects is that we can use the traditional plotting features of <code>R</code>. The following command give’s us a plot of Chicago’s Census Tracts:</p>
<div>
<pre><code><span>plot</span><span>(</span><span>chi.poly</span><span>)</span><span>
</span></code></pre>
</div>
<p><img align="middle" src="https://i2.wp.com/ignaciomsarmiento.github.io/assets/images/spatial/unnamed-chunk-9-1.png?w=400&ssl=1" data-recalc-dims="1"> </p>
<p>but we can go a step further and make nicer plots using the <code>leaflet</code> package. This generates an interactive map that can be rendered on HTML pages.</p>
<div>
<pre><code><span>library</span><span>(</span><span>leaflet</span><span>)</span><span>
</span><span>leaflet</span><span>(</span><span>chi.poly</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>addPolygons</span><span>(</span><span>stroke</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>,</span><span> </span><span>fillOpacity</span><span> </span><span>=</span><span> </span><span>0.5</span><span>,</span><span> </span><span>smoothFactor</span><span> </span><span>=</span><span> </span><span>0.5</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>addTiles</span><span>()</span><span> </span><span>#adds a map tile, the default is OpenStreetMap
</span></code></pre>
</div>
<p></p>
<p></p>
<p></p>
<p>we can add color using the package <code>RColorBrewer</code></p>
<div>
<pre><code><span>require</span><span>(</span><span>RColorBrewer</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## Loading required package: RColorBrewer
</code></pre>
</div>
<div>
<pre><code><span>qpal</span><span>&lt;-</span><span>colorQuantile</span><span>(</span><span>&quot;OrRd&quot;</span><span>,</span><span> </span><span>chi.poly</span><span>@</span><span>data</span><span>$</span><span>violent</span><span>,</span><span> </span><span>n</span><span>=</span><span>9</span><span>)</span><span> </span><span>#define a palette with 7 breaks
</span><span>
</span><span>leaflet</span><span>(</span><span>chi.poly</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>addPolygons</span><span>(</span><span>stroke</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>,</span><span> </span><span>fillOpacity</span><span> </span><span>=</span><span> </span><span>.8</span><span>,</span><span> </span><span>smoothFactor</span><span> </span><span>=</span><span> </span><span>0.2</span><span>,</span><span> </span><span>color</span><span> </span><span>=</span><span> </span><span>~</span><span>qpal</span><span>(</span><span>violent</span><span>)</span><span>
</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>addTiles</span><span>()</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## Warning in doColorRamp(colorMatrix, x, alpha, ifelse(is.na(na.color), &quot;&quot;, :
## '.Random.seed' is not an integer vector but of type 'NULL', so ignored
</code></pre>
</div>
<p></p>
<p></p>
<p></p>
<p>The <code>colorQuantile</code> function of the <code>leaflet</code> package maps values of the data to colors following a palette. In this case I’ve specified a palette of Oranges and Reds, for more palettes you can access the help file for RColorBrewer: <code>?RColorBrewer</code>.</p>
<h1>Spatial Econometrics in R</h1>
<p>When dealing with space one must bear in mind Tobler’s first law of geography “Everything is related to everything else, but close things are more related than things that are far apart”(Tobler (1979)). In this section we’ll focus on the specification of spatial dependence, on specification tests to detect spatial dependence in regressions models and on basic regression models that incorporate spatial dependence. We’ll illustrate this using the data in the shapefile loaded in the previous section.</p>
<h2>OLS</h2>
<p>The traditional approach for many years has been to ignore the spatial dependence of the data and just run an OLS regression.</p>
<p></p>
<p>In <code>R</code> this is achieved with the <code>lm</code> function. For example,</p>
<div>
<pre><code><span>chi.ols</span><span>&lt;-</span><span>lm</span><span>(</span><span>violent</span><span>~</span><span>est_fcs_rt</span><span>+</span><span>bls_unemp</span><span>,</span><span> </span><span>data</span><span>=</span><span>chi.poly</span><span>@</span><span>data</span><span>)</span><span>
</span></code></pre>
</div>
<p>I’ve specified the “model” as <code>violent~est_fcs_rt+bls_unemp</code> where violent is the dependent variable and, <code>est_fcs_rt</code> and <code>bls_unemp</code> are the explanatory variable. I’ve also specified the data set which is the slot data of our <code>shapefile</code>. Note that to access this slot I use the <code>@</code> symbol. This line does not return anything because we have created an <code>lm</code> object that I called <code>chi.ols</code>. To see the results, we use the <code>summary</code> function</p>
<div>
<pre><code><span>summary</span><span>(</span><span>chi.ols</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>##
## Call:
## lm(formula = violent ~ est_fcs_rt + bls_unemp, data = chi.poly@data)
##
## Residuals:
##     Min      1Q  Median      3Q     Max
## -892.02  -77.02  -23.73   41.90 1238.22
##
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)
## (Intercept)  -18.627     45.366  -0.411    0.681
## est_fcs_rt    28.298      1.435  19.720   &lt;2e-16 ***
## bls_unemp     -0.308      5.770  -0.053    0.957
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 157.3 on 894 degrees of freedom
## Multiple R-squared:  0.3141, Adjusted R-squared:  0.3126
## F-statistic: 204.7 on 2 and 894 DF,  p-value: &lt; 2.2e-16
</code></pre>
</div>
<p>The problem with ignoring the spatial structure of the data implies that the OLS estimates in the non spatial model may be biased, inconsistent or inefficient, depending on what is the true underlying dependence (for more see Anselin and Bera (1998)).</p>
<h2>Modeling Spatial Dependence</h2>
<p>We now take a closer look at spatial dependence, or to be more precise on it’s weaker expression spatial autocorrelation. Spatial autocorrelation measures the degree to which a phenomenon of interest is correlated to itself in space (Cliff and Ord (1973)). In other words, similar values appear close to each other, or cluster, in space (positive spatial autocorrelation) or neighboring values are dissimilar (negative spatial autocorrelation). Null spatial autocorrelation indicates that the spatial pattern is random. Following Anselin and Bera (1998) we can express the existence of spatial autocorrelation with the following moment condition:</p>
<p>\begin{equation}<br>
Cov(y_{i},y_{j})\neq 0\,\,\,\, for\,\,\,\,i\neq j<br>
\end{equation}<br>
were <em>y</em><sub><em>i</em></sub> and <em>y</em><sub><em>j</em></sub> are observations on a random variable at locations <em>i</em> and <em>j</em>. The problem here is that we need to estimate <em>N</em> by <em>N</em> covariance terms directly for <em>N</em> observations. To overcome this problem we impose restrictions on the nature of the interactions. One type of restriction is to define for each data point a relevant “neighborhood set”. In spatial econometrics this is operationalized via the <strong>spatial weights matrix</strong>. The matrix usually denoted by <em>W</em> is a <em>N</em> by <em>N</em> positive and symmetric matrix which denotes fore each observation (row) those locations (columns) that belong to its neighborhood set as nonzero elements (Anselin and Bera (1998), Arbia (2014)), the typical element is then:</p>
<p></p>
<p><em>N</em>(<em>i</em>) being the set of neighbors of location <em>j</em>. By convention, the diagonal elements are set to zero, i.e. . To help with the interpretation the matrix is often row standardized such that the elements of a given row add to one.</p>
<p>The specification of the neighboring set is quite arbitrary and there’s a wide range of suggestions in the literature. One popular way is to use one of the two following criteria:</p>
<ul>
<li>Rook criterion: two units are close to one another if they share a side</li>
</ul>
<p><img align="middle" src="https://i0.wp.com/ignaciomsarmiento.github.io/assets/images/spatial/rook-1.png?w=400&ssl=1" data-recalc-dims="1"> </p>
<ul>
<li>Queen criterion: two units are close if they share a side or an edge.</li>
</ul>
<p><img align="middle" src="https://i2.wp.com/ignaciomsarmiento.github.io/assets/images/spatial/queen-1.png?w=400&ssl=1" data-recalc-dims="1"> </p>
<p>Another used approach is to denote two observations as neighbors if they are within a certain distance, i.e.,  where  is the distance between location  and  .</p>
<p>Here we’ll focus on using the <em>queen</em> criterion and we encourage the reader to experiment with the <em>rook</em> criterion. In <code>R</code> to obtain the weights matrix we make use of two functions. In the first step we use <code>poly2nb</code> which builds a neighbors list, if the option <code>queen=TRUE</code> is specified it will be build using the queen criterion. If <code>FALSE</code> is specified, then the rook criteria will be used. The next step is to supplement the neighbors list with the spatial weights. The option <code>W</code> row standardizes the matrix.</p>
<div>
<pre><code><span>list.queen</span><span>&lt;-</span><span>poly2nb</span><span>(</span><span>chi.poly</span><span>,</span><span> </span><span>queen</span><span>=</span><span>TRUE</span><span>)</span><span>
</span><span>W</span><span>&lt;-</span><span>nb2listw</span><span>(</span><span>list.queen</span><span>,</span><span> </span><span>style</span><span>=</span><span>&quot;W&quot;</span><span>,</span><span> </span><span>zero.policy</span><span>=</span><span>TRUE</span><span>)</span><span>
</span><span>W</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## Characteristics of weights list object:
## Neighbour list object:
## Number of regions: 897
## Number of nonzero links: 6140
## Percentage nonzero weights: 0.7631036
## Average number of links: 6.845039
##
## Weights style: W
## Weights constants summary:
##     n     nn  S0       S1       S2
## W 897 804609 897 274.4893 3640.864
</code></pre>
</div>
<p>We can plot the link distribution with the usual <code>plot</code> function</p>
<div>
<pre><code><span>plot</span><span>(</span><span>W</span><span>,</span><span>coordinates</span><span>(</span><span>chi.poly</span><span>))</span><span>
</span></code></pre>
</div>
<p><img align="middle" src="https://i1.wp.com/ignaciomsarmiento.github.io/assets/images/spatial/neighbors_plot-1.png?w=400&ssl=1" data-recalc-dims="1"> </p>
<p>To obtain the weight matrix based on distances we use two functions: <code>coordinates</code> that will retrieve the centroid coordinates of the census tracts polygons and <code>dnearneigh</code> that will identify neighbors between two distances in kilometers measured using Euclidean distance. For example, to find neighbors within 1 kilometer we do:</p>
<div>
<pre><code><span>coords</span><span>&lt;-</span><span>coordinates</span><span>(</span><span>chi.poly</span><span>)</span><span>
</span><span>W_dist</span><span>&lt;-</span><span>dnearneigh</span><span>(</span><span>coords</span><span>,</span><span>0</span><span>,</span><span>1</span><span>,</span><span>longlat</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span></code></pre>
</div>
<p>I encourage you to compare the link distributions for these three ways of defining neighbors.</p>
<h3>Spatial Autoregressive (SAR) Models</h3>
<p>Spatial lag dependence in a regression setting can be modeled similar to an autoregressive process in time series. Formally,</p>
<p></p>
<p>The presence of the term  induces a nonzero correlation with the error term, similar to the presence of an endogenous variable, but different from the time series context. Contrarious to time series,  is always correlated with  irrespective of the structure of the errors. This implies that OLS estimates in the non spatial model will be biased and inconsistent. (Anselin and Bera (1998))</p>
<h3>Spatial Error Models (SEM)</h3>
<p>Another way to model spatial autocorrelation in a regression model is to specify the autoregressive process in the error term:</p>
<p></p>
<p>with</p>
<p></p>
<p>If this is the “true” form of spatial dependence OLS estimates will be unbiased but inefficient.</p>
<h2>Testing for spatial autocorrelation</h2>
<p>There are multiple tests for testing the presence of spatial autocorrelation. In this note we’ll focus on a restricted set: Moran’s I test and Lagrange Multiplier tests.</p>
<h3>Moran’s I Test</h3>
<p>Moran’s I test was originally developed as a two-dimensional analog of Durbin-Watson’s test</p>
<p></p>
<p>where  is a vector of OLS residuals, ,  is the row standardized spatial weights matrix.(For more detail see Anselin and Bera (1998))</p>
<p>To perform a Moran test on our data we need two inputs, an lm regression object (estimated in the OLS section) and the spatial weight matrix</p>
<div>
<pre><code><span>moran.lm</span><span>&lt;-</span><span>lm.morantest</span><span>(</span><span>chi.ols</span><span>,</span><span> </span><span>W</span><span>,</span><span> </span><span>alternative</span><span>=</span><span>&quot;two.sided&quot;</span><span>)</span><span>
</span><span>print</span><span>(</span><span>moran.lm</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>##
##  Global Moran I for regression residuals
##
## data:
## model: lm(formula = violent ~ est_fcs_rt + bls_unemp, data =
## chi.poly@data)
## weights: W
##
## Moran I statistic standard deviate = 11.785, p-value &lt; 2.2e-16
## alternative hypothesis: two.sided
## sample estimates:
## Observed Moran I      Expectation         Variance
##     0.2142252370    -0.0020099108     0.0003366648
</code></pre>
</div>
<p>The computation of the statistic is relative to a given choice of the spatial weights W. Different specifications of the weights matrix will give different results. I encourage the reader to try this with the <em>rook</em> contiguity criterion.</p>
<h3>Lagrange Multiplier Test</h3>
<p>A nice feature of Moran’s I test is that i has high power against a wide range of alternatives (Anselin and Bera (1998)). However, it does not guide us in the selection of alternative models. On the other hand, Lagrange Multiplier test specify the alternative hypothesis which will help us with the task. The LM tests for spatial dependence are included in the <code>lm.LMtests</code> function and include as alternatives the presence of a spatial lag and the presence of a spatial lag in the error term. Both tests, as well as their robust forms are included in the <code>lm.LMtests</code> function. To call them we use the option <code>test=&quot;all&quot;</code>. Again, a regression object and a spatial listw object must be passed as arguments:</p>
<div>
<pre><code><span>LM</span><span>&lt;-</span><span>lm.LMtests</span><span>(</span><span>chi.ols</span><span>,</span><span> </span><span>W</span><span>,</span><span> </span><span>test</span><span>=</span><span>&quot;all&quot;</span><span>)</span><span>
</span><span>print</span><span>(</span><span>LM</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>##
##  Lagrange multiplier diagnostics for spatial dependence
##
## data:
## model: lm(formula = violent ~ est_fcs_rt + bls_unemp, data =
## chi.poly@data)
## weights: W
##
## LMerr = 134.52, df = 1, p-value &lt; 2.2e-16
##
##
##  Lagrange multiplier diagnostics for spatial dependence
##
## data:
## model: lm(formula = violent ~ est_fcs_rt + bls_unemp, data =
## chi.poly@data)
## weights: W
##
## LMlag = 182.18, df = 1, p-value &lt; 2.2e-16
##
##
##  Lagrange multiplier diagnostics for spatial dependence
##
## data:
## model: lm(formula = violent ~ est_fcs_rt + bls_unemp, data =
## chi.poly@data)
## weights: W
##
## RLMerr = 0.00066762, df = 1, p-value = 0.9794
##
##
##  Lagrange multiplier diagnostics for spatial dependence
##
## data:
## model: lm(formula = violent ~ est_fcs_rt + bls_unemp, data =
## chi.poly@data)
## weights: W
##
## RLMlag = 47.653, df = 1, p-value = 5.089e-12
##
##
##  Lagrange multiplier diagnostics for spatial dependence
##
## data:
## model: lm(formula = violent ~ est_fcs_rt + bls_unemp, data =
## chi.poly@data)
## weights: W
##
## SARMA = 182.18, df = 2, p-value &lt; 2.2e-16
</code></pre>
</div>
<p>Since <code>LMerr</code> and <code>LMlag</code> are both statistically significant different from zero, we need to look at their robust counterparts. These robust counterparts are actually robust to the presence of the other “type” of autocorrelation. The robust version of the tests suggest that the lag model is the more likely alternative.</p>
<h2>Running Spatial Regressions</h2>
<h3>SAR Models</h3>
<p>The estimation of the SAR model can be approached in two ways. One way is to assume normality of the error term and use maximum likelihood. This is achieved in <code>R</code> with the function <code>lagsarlm</code></p>
<div>
<pre><code><span>sar.chi</span><span>&lt;-</span><span>lagsarlm</span><span>(</span><span>violent</span><span>~</span><span>est_fcs_rt</span><span>+</span><span>bls_unemp</span><span>,</span><span> </span><span>data</span><span>=</span><span>chi.poly</span><span>@</span><span>data</span><span>,</span><span> </span><span>W</span><span>)</span><span>
</span><span>summary</span><span>(</span><span>sar.chi</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>##
## Call:
## lagsarlm(formula = violent ~ est_fcs_rt + bls_unemp, data = chi.poly@data,
##     listw = W)
##
## Residuals:
##      Min       1Q   Median       3Q      Max
## -519.127  -65.003  -15.226   36.423 1184.193
##
## Type: lag
## Coefficients: (asymptotic standard errors)
##             Estimate Std. Error z value Pr(>|z|)
## (Intercept) -93.7885    41.3162  -2.270  0.02321
## est_fcs_rt   15.6822     1.5600  10.053  &lt; 2e-16
## bls_unemp     8.8949     5.2447   1.696  0.08989
##
## Rho: 0.49037, LR test value: 141.33, p-value: &lt; 2.22e-16
## Asymptotic standard error: 0.039524
##     z-value: 12.407, p-value: &lt; 2.22e-16
## Wald statistic: 153.93, p-value: &lt; 2.22e-16
##
## Log likelihood: -5738.047 for lag model
## ML residual variance (sigma squared): 20200, (sigma: 142.13)
## Number of observations: 897
## Number of parameters estimated: 5
## AIC: 11486, (AIC for lm: 11625)
## LM test for residual autocorrelation
## test value: 8.1464, p-value: 0.0043146
</code></pre>
</div>
<p>Another way is to use <em>2SLS</em> using the function <code>stsls</code>. I leave this to the reader so he/she can compare the results to the MLE approach. The function is:</p>
<div>
<pre><code><span>sar2sls.chi</span><span>&lt;-</span><span>stsls</span><span>(</span><span>violent</span><span>~</span><span>est_fcs_rt</span><span>+</span><span>bls_unemp</span><span>,</span><span> </span><span>data</span><span>=</span><span>chi.poly</span><span>@</span><span>data</span><span>,</span><span> </span><span>W</span><span>)</span><span>
</span><span>summary</span><span>(</span><span>sar2sls.chi</span><span>)</span><span>
</span></code></pre>
</div>
<p>We then can compare the residuals of the <em>OLS</em> regression to the residuals of the <em>spatial autoregressive model</em>. To access the residuals for the OLS model and the SAR model we simply do</p>
<div>
<pre><code><span>chi.poly</span><span>@</span><span>data</span><span>$</span><span>chi.ols.res</span><span>&lt;-</span><span>resid</span><span>(</span><span>chi.ols</span><span>)</span><span> </span><span>#residuals ols
</span><span>
</span><span>chi.poly</span><span>@</span><span>data</span><span>$</span><span>chi.sar.res</span><span>&lt;-</span><span>resid</span><span>(</span><span>sar.chi</span><span>)</span><span> </span><span>#residual sar
</span></code></pre>
</div>
<p>In this step I’ve create a new variable in the data portion of the shapefile that will help with the plotting of the residuals. To plot the residuals, I use the <code>spplot</code> function in the <code>spdep</code> package. The arguments are the shapefile, the variable that we want to plot, the number of breaks and the colors we are going to use. To specify the colors, we use the Red and Blues (<code>RdBu</code>) palette from the <code>RColorBrewer</code> package.</p>
<div>
<pre><code><span>spplot</span><span>(</span><span>chi.poly</span><span>,</span><span>&quot;chi.ols.res&quot;</span><span>,</span><span> </span><span>at</span><span>=</span><span>seq</span><span>(</span><span>min</span><span>(</span><span>chi.poly</span><span>@</span><span>data</span><span>$</span><span>chi.ols.res</span><span>,</span><span>na.rm</span><span>=</span><span>TRUE</span><span>),</span><span>max</span><span>(</span><span>chi.poly</span><span>@</span><span>data</span><span>$</span><span>chi.ols.res</span><span>,</span><span>na.rm</span><span>=</span><span>TRUE</span><span>),</span><span>length</span><span>=</span><span>12</span><span>),</span><span>col.regions</span><span>=</span><span>rev</span><span>(</span><span>brewer.pal</span><span>(</span><span>11</span><span>,</span><span>&quot;RdBu&quot;</span><span>)))</span><span>
</span></code></pre>
</div>
<p><img align="middle" src="https://i2.wp.com/ignaciomsarmiento.github.io/assets/images/spatial/unnamed-chunk-17-1.png?w=400&ssl=1" data-recalc-dims="1"> </p>
<div>
<pre><code><span>spplot</span><span>(</span><span>chi.poly</span><span>,</span><span>&quot;chi.sar.res&quot;</span><span>,</span><span>at</span><span>=</span><span>seq</span><span>(</span><span>min</span><span>(</span><span>chi.poly</span><span>@</span><span>data</span><span>$</span><span>chi.sar.res</span><span>,</span><span>na.rm</span><span>=</span><span>TRUE</span><span>),</span><span>max</span><span>(</span><span>chi.poly</span><span>@</span><span>data</span><span>$</span><span>chi.sar</span><span>,</span><span>na.rm</span><span>=</span><span>TRUE</span><span>),</span><span> </span><span>length</span><span>=</span><span>12</span><span>),</span><span> </span><span>col.regions</span><span>=</span><span>rev</span><span>(</span><span>brewer.pal</span><span>(</span><span>11</span><span>,</span><span>&quot;RdBu&quot;</span><span>)))</span><span>
</span></code></pre>
</div>
<p><img align="middle" src="https://i1.wp.com/ignaciomsarmiento.github.io/assets/images/spatial/unnamed-chunk-17-2.png?w=400&ssl=1" data-recalc-dims="1"> </p>
<h4>Marginal Effects</h4>
<p>Note that the presence of the spatial weights matrix makes marginal effects richer and slightly more complicated than in the “traditional” OLS model. We’ll have three impact measures suggested by Pace and LeSage (2009) and is done in <code>R</code> with the function <code>impacts</code></p>
<div>
<pre><code><span>impacts</span><span>(</span><span>sar.chi</span><span>,</span><span> </span><span>listw</span><span>=</span><span>W</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## Impact measures (lag, exact):
##               Direct  Indirect    Total
## est_fcs_rt 16.434479 14.336896 30.77137
## bls_unemp   9.321585  8.131842 17.45343
</code></pre>
</div>
<p>The direct impact refers to average total impact of a change of an independent variable on the dependent fore each observation, i.e., $n^{-1}\sum_{i=1}^{n}\frac{\partial E(y_{i})}{\partial X_{i}}$, the indirect impact which is the sum of the impact produced on one single observation by all other observations and the impact of one observation on all the other. The total is the summation of the two</p>
<h3>SEM Models</h3>
<p>On the other hand, if we want to estimate the Spatial Error Model we have two approaches again. First, we can use Maximum Likelihood as before, with the function <code>errorsarlm</code></p>
<div>
<pre><code><span>errorsalm.chi</span><span>&lt;-</span><span>errorsarlm</span><span>(</span><span>violent</span><span>~</span><span>est_fcs_rt</span><span>+</span><span>bls_unemp</span><span>,</span><span> </span><span>data</span><span>=</span><span>chi.poly</span><span>@</span><span>data</span><span>,</span><span> </span><span>W</span><span>)</span><span>
</span><span>summary</span><span>(</span><span>errorsalm.chi</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>##
## Call:
## errorsarlm(formula = violent ~ est_fcs_rt + bls_unemp, data = chi.poly@data,
##     listw = W)
##
## Residuals:
##      Min       1Q   Median       3Q      Max
## -650.506  -64.355  -22.646   35.461 1206.346
##
## Type: error
## Coefficients: (asymptotic standard errors)
##             Estimate Std. Error z value Pr(>|z|)
## (Intercept)  -1.2624    43.0509 -0.0293   0.9766
## est_fcs_rt   19.4620     1.9450 10.0062   &lt;2e-16
## bls_unemp     4.0380     5.5134  0.7324   0.4639
##
## Lambda: 0.52056, LR test value: 109.68, p-value: &lt; 2.22e-16
## Asymptotic standard error: 0.042291
##     z-value: 12.309, p-value: &lt; 2.22e-16
## Wald statistic: 151.51, p-value: &lt; 2.22e-16
##
## Log likelihood: -5753.875 for error model
## ML residual variance (sigma squared): 20796, (sigma: 144.21)
## Number of observations: 897
## Number of parameters estimated: 5
## AIC: 11518, (AIC for lm: 11625)
</code></pre>
</div>
<p>The same plot for the SEM residuals can be done as before and is left for the reader. A second approach is use Feasible Generalized Least Squares (GLS) with the function <code>GMerrorsar</code>. The function is:</p>
<div>
<pre><code><span>fgls.chi</span><span>&lt;-</span><span>GMerrorsar</span><span>(</span><span>violent</span><span>~</span><span>est_fcs_rt</span><span>+</span><span>bls_unemp</span><span>,</span><span> </span><span>data</span><span>=</span><span>chi.poly</span><span>@</span><span>data</span><span>,</span><span> </span><span>W</span><span>)</span><span>
</span><span>summary</span><span>(</span><span>fgls.chi</span><span>)</span><span>
</span></code></pre>
</div>
<p>Finally, if we look at the likelihood for the SAR model and SEM model we see that we achieve a lower value for the SAR model that was the model favored by the LMtests. The residuals plot presented above still show some presence of spatial autocorrelation. It’s very likely that the a more complete model is specified. The literature has expanded to more complex models. The reader is encouraged to read Anselin and Bera (1998), Arbia (2014) and Pace and LeSage (2009) for more detailed and complete introductions on Spatial Econometrics.</p>
<p><strong>Comments and suggestions are always welcomed. You can send them to <code>srmntbr2</code> at <code>illinois.edu</code>. The usual disclaimers apply.</strong></p>
<h1>References</h1>
<p>Anselin, Luc. 2003. “An Introduction to Spatial Regression Analysis in R.” <em>Available at: Https://Geodacenter.asu.edu/Drupal_files/Spdepintro.pdf</em>.</p>
<p>Anselin, Luc, and Anil K Bera. 1998. “Spatial Dependence in Linear Regression Models with an Introduction to Spatial Econometrics.” <em>Statistics Textbooks and Monographs</em> 155. MARCEL DEKKER AG: 237–90.</p>
<p>Arbia, Giuseppe. 2014. <em>A Primer for Spatial Econometrics: With Applications in R</em>. Palgrave Macmillan.</p>
<p>Bivand, Roger S, Edzer J Pebesma, and Virgilio Gomez-Rubio. 2008. <em>Applied Spatial Data Analysis with R. Springer</em>. Springer.</p>
<p>Bivand, Roger, and Nicholas Lewin-Koh. 2016. <em>Maptools: Tools for Reading and Handling Spatial Objects</em>. <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=maptools">https://CRAN.R-project.org/package=maptools</a>.</p>
<p>Bivand, Roger, and Gianfranco Piras. 2015. “Comparing Implementations of Estimation Methods for Spatial Econometrics.” <em>Journal of Statistical Software</em> 63 (18): 1–36. <a target="_blank" rel="nofollow" href="http://www.jstatsoft.org/v63/i18/">http://www.jstatsoft.org/v63/i18/</a>.</p>
<p>Bivand, Roger, Jan Hauke, and Tomasz Kossowski. 2013. “Computing the Jacobian in Gaussian Spatial Autoregressive Models: An Illustrated Comparison of Available Methods.” <em>Geographical Analysis</em> 45 (2): 150–79. <a target="_blank" rel="nofollow" href="http://www.jstatsoft.org/v63/i18/">http://www.jstatsoft.org/v63/i18/</a>.</p>
<p>Cheng, Joe, and Yihui Xie. 2015. <em>Leaflet: Create Interactive Web Maps with the Javascript ’Leaflet’ Library</em>. <a target="_blank" rel="nofollow" href="http://rstudio.github.io/leaflet/">http://rstudio.github.io/leaflet/</a>.</p>
<p>Cliff, Andrew David, and J Keith Ord. 1973. <em>Spatial Autocorrelation</em>. Vol. 5. Pion London.</p>
<p>ESRI, Environmental Systems Research Institute. 1998. “ESRI Shapefile Technical Description.” <em>Available at: Https://Www.esri.com/Library/Whitepapers/Pdfs/Shapefile.pdf</em>.</p>
<p>Neuwirth, Erich. 2014. <em>RColorBrewer: ColorBrewer Palettes</em>. <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=RColorBrewer">https://CRAN.R-project.org/package=RColorBrewer</a>.</p>
<p>Pace, R Kelley, and JP LeSage. 2009. “Introduction to Spatial Econometrics.” <em>Boca Raton, FL: Chapman &amp;Hall/CRC</em>.</p>
<p>Tobler, WR. 1979. “Cellular Geography.” In <em>Philosophy in Geography</em>, 379–86. Springer.</p>
<p>Wickham, Hadley. 2015. <em>R Packages</em>. “O’Reilly Media, Inc.”</p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://ignaciomsarmiento.github.io/2017/02/07/An-Introduction-to-Spatial-Econometrics-in-R.html"> Ignacio Sarmiento Barbieri</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/qVWY9po2pNA"></a></div>