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_persUse 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.038453928We 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.400641Then calculate the pseudo p-value using the formula \((M + 1) / (R + 1)\)
# simulated p-value
(sum(observed[["I"]] <= permutes) + 1) / (299 + 1)
#> [1] 0.003333333This is the approach taken by Pysal and by sfdep where other methods do not apply or are not provided by spdep.