Conditional Permutations with sfdep

In the lattice approach to spatial analysis, calculating p-values is often done based on a conditional permutation approach as outlined by Anselin 1995.

Conditional permutation can be summed up with the question “if I were to hold this observation constant, and change it’s neighbors, will my statistic be the same?”

First obtain our neighbors and weights lists, as well as our numeric variable.

library(sfdep)

nb <- st_contiguity(guerry)
wt <- st_weights(nb)
x <- guerry$crime_pers

Use cond_permute_nb() to create a conditional permutation of the neighbors list. Then calculate the Moran’s I 299 times with a different permutation each time. These results are stores in permutes.

permutes <- purrr::map_dbl(1:299, ~{
 p_nb <- cond_permute_nb(nb)
 p_wt <- st_weights(p_nb)
 global_moran(x, p_nb, p_wt)[["I"]]
})

permutes[1:10]
#>  [1]  0.003859476 -0.036206668 -0.053463307 -0.054460671 -0.050918017
#>  [6] -0.073258387 -0.052230281 -0.050221229 -0.102663758 -0.038453928

We then find the observed Moran’s I statistics.

# the observed global moran
observed <- global_moran(x, nb, wt)
observed
#> $I
#> [1] 0.4114597
#> 
#> $K
#> [1] 2.400641

Then calculate the pseudo p-value using the formula \((M + 1) / (R + 1)\)

# simulated p-value
(sum(observed[["I"]] <= permutes) + 1) / (299 + 1)
#> [1] 0.003333333

This is the approach taken by Pysal and by sfdep where other methods do not apply or are not provided by spdep.