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)
<- st_contiguity(guerry)
nb <- st_weights(nb)
wt <- guerry$crime_pers x
```

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`

.

```
<- purrr::map_dbl(1:299, ~{
permutes <- cond_permute_nb(nb)
p_nb <- st_weights(p_nb)
p_wt global_moran(x, p_nb, p_wt)[["I"]]
})
1:10]
permutes[#> [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
<- global_moran(x, nb, wt)
observed
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.