vignettes/spatial.Rmd
spatial.RmdIf we have data on the longitudes and latitudes of taxa, sometimes it is useful to control for this spatial location to ensure that our model is capturing deep ancestral relationships rather than shared environmental effects or more recent diffusion among neighbours.
The lon_lat argument in the coev_fit()
function allows us to easily control for spatial proximity. This
argument takes a data frame of longitude and latitude coordinates (in
decimal degrees) for taxa on the phylogeny. If longitude and latitude
values are inputted by the user, the function calculates the Euclidean
distances between these points on a unit sphere and includes a Gaussian
process over these distances for each variable in the model.
When studying the coevolution of political and religious authority in Austronesian societies, we would like to ensure that our results are due to coevolution over deep cultural time rather than more recent borrowing among societies with close geographic proximity.
Here are the longitude and latitude values for the first five Austronesian societies:
authority$coordinates[1:5, ]# A tibble: 5 × 3
id latitude longitude
<chr> <dbl> <dbl>
1 Aiwoo -10.3 166.
2 Alune -3.1 128.
3 AnejomAneityum -20.2 170.
4 Anuta -11.6 170.
5 Atoni -9.7 124.
We can include these spatial coordinates in the model. The distance matrix is scaled to vary between 0 and 1 under the hood to improve model sampling.
fit <-
coev_fit(
data = authority$data,
variables = list(
political_authority = "ordered_logistic",
religious_authority = "ordered_logistic"
),
id = "language",
tree = authority$phylogeny,
# declare longitude and latitude values
lon_lat = authority$coordinates,
# set manual prior
prior = list(A_offdiag = "normal(0, 2)"),
# additional arguments for cmdstanr
parallel_chains = 4,
iter_sampling = 2000,
iter_warmup = 2000,
refresh = 0,
seed = 1
)Running MCMC with 4 parallel chains...
Chain 2 finished in 662.1 seconds.
Chain 3 finished in 674.2 seconds.
Chain 4 finished in 680.5 seconds.
Chain 1 finished in 916.1 seconds.
All 4 chains finished successfully.
Mean chain execution time: 733.2 seconds.
Total execution time: 916.3 seconds.
summary(fit)Variables: political_authority = ordered_logistic
religious_authority = ordered_logistic
Data: authority$data (Number of observations: 97)
Phylogeny: authority$phylogeny (Number of trees: 1)
Draws: 4 chains, each with iter = 2000; warmup = 2000; thin = 1
total post-warmup draws = 8000
Autoregressive selection effects:
Estimate Est.Error 2.5% 97.5% Rhat Bulk_ESS Tail_ESS
political_authority -0.70 0.55 -2.04 -0.03 1.00 5198 3665
religious_authority -0.77 0.57 -2.14 -0.03 1.00 4905 2919
Cross selection effects:
Estimate Est.Error 2.5% 97.5% Rhat Bulk_ESS Tail_ESS
political_authority ⟶ religious_authority 1.97 1.25 -0.67 4.37 1.00 2512 2004
religious_authority ⟶ political_authority 1.49 1.28 -1.08 4.01 1.00 1885 3395
Drift parameters:
Estimate Est.Error 2.5% 97.5% Rhat Bulk_ESS Tail_ESS
sd(political_authority) 1.26 0.74 0.06 2.83 1.00 974 1590
sd(religious_authority) 0.94 0.64 0.04 2.40 1.01 1590 2316
cor(political_authority,religious_authority) 0.12 0.33 -0.54 0.70 1.00 3963 5106
Continuous time intercept parameters:
Estimate Est.Error 2.5% 97.5% Rhat Bulk_ESS Tail_ESS
political_authority 0.41 0.97 -1.51 2.32 1.00 6112 5721
religious_authority 0.42 0.93 -1.37 2.26 1.00 6920 5885
Ordinal cutpoint parameters:
Estimate Est.Error 2.5% 97.5% Rhat Bulk_ESS Tail_ESS
political_authority[1] -1.57 1.03 -3.56 0.44 1.00 4403 6008
political_authority[2] -0.85 1.01 -2.81 1.19 1.00 4441 5608
political_authority[3] 1.30 1.06 -0.70 3.47 1.00 3242 5209
religious_authority[1] -1.87 1.06 -3.94 0.24 1.00 4308 5009
religious_authority[2] -1.16 1.04 -3.18 0.96 1.00 4488 4854
religious_authority[3] 1.54 1.10 -0.53 3.76 1.00 3936 5472
Gaussian Process parameters for distances:
Estimate Est.Error 2.5% 97.5% Rhat Bulk_ESS Tail_ESS
rho(political_authority) 0.10 0.05 0.04 0.20 1.00 781 1298
rho(religious_authority) 0.07 0.04 0.03 0.18 1.00 502 461
sdgp(political_authority) 1.87 0.73 0.72 3.59 1.00 2167 2185
sdgp(religious_authority) 2.40 0.80 1.04 4.16 1.00 2358 2639
Warning: There were 10 divergent transitions after warmup.
http://mc-stan.org/misc/warnings.html#divergent-transitions-after-warmup
The summary output shows that the model has estimated the parameters for two Gaussian process functions over geographic locations, one for each variable.
In addition, it is possible to change the underlying covariance
kernel for the Gaussian processes using the dist_cov
argument and estimate approximate Hilbert-space Gaussian processes using
the dist_k argument. The latter may be particularly useful
for large datasets where exact Gaussian processes are intractable. See
help(coev_fit) for more details.