| Title: | Fit Bayesian Generalized Dynamic Phylogenetic Models using 'Stan' or 'JAX' |
|---|---|
| Description: | Fit Bayesian generalized dynamic phylogenetic models using 'Stan' or 'JAX'. The package allows an arbitrary number of variables with different response distributions to coevolve on a phylogenetic tree via an Ornstein-Uhlenbeck evolutionary process, allowing users to assess directionality between coevolving variables. The optional JAX backend enables high-performance sampling with NumPyro and potential GPU acceleration via 'reticulate'. |
| Authors: | Scott Claessens [aut, cre] (ORCID: <https://orcid.org/0000-0002-3562-6981>), Erik Ringen [aut] (ORCID: <https://orcid.org/0000-0002-3565-6961>), Rob Moss [rev] (ORCID: <https://orcid.org/0000-0002-4568-2012>), Krzysztof Bartoszek [rev] (ORCID: <https://orcid.org/0000-0002-5816-4345>) |
| Maintainer: | Scott Claessens <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 1.2.1 |
| Built: | 2026-10-07 08:29:37 UTC |
| Source: | https://github.com/ScottClaessens/coevolve |
This dataset and associated phylogeny describes the states of political and religious authority in 97 Austronesian societies. These data were originally compiled in Sheehan et al. (2023). Political authority is defined as a right to manage interactions between living human beings, whereas religious authority is defined as a right to manage interactions between living human beings and supernatural agents or powers. Authority is coded as being absent, sublocal (smaller than the local community), local (coextensive with the local community), or supralocal (consisting of more than one local community).
authorityauthority
A list containing a dataset, an associated language phylogeny, and associated geographic coordinates. The phylogeny is a pruned maximum clade credibility tree for 97 Austronesian languages. The coordinates are in a data frame, with longitude and latitude values measured in decimal degrees. The dataset is a data frame with 97 observations and three variables:
The name of the Austronesian language linked to each society
An ordered factor indicating whether political authority is absent, sublocal, local, or supralocal in each society
An ordered factor indicating whether religious authority is absent, sublocal, local, or supralocal in each society
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen, E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political authority in Austronesian societies. Nature Human Behaviour, 7(1), 38-45.
## Not run: # fit model to authority data m <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # arguments for cmdstanr::sample() parallel_chains = 4, seed = 1, # set prior manually prior = list(A_offdiag = "normal(0, 2)") ) # print model summary summary(m) # plot delta theta coev_plot_delta_theta(m) ## End(Not run)## Not run: # fit model to authority data m <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # arguments for cmdstanr::sample() parallel_chains = 4, seed = 1, # set prior manually prior = list(A_offdiag = "normal(0, 2)") ) # print model summary summary(m) # plot delta theta coev_plot_delta_theta(m) ## End(Not run)
Extracts posterior estimates of trait values at internal nodes of the
phylogenetic tree from a fitted coevfit object. By default,
estimates are returned on the latent (eta) scale; use
scale = "response" to apply the inverse link for each variable's
response distribution. The latent eta parameters in the model
correspond directly to nodes in the phylogeny, making ancestral state
reconstruction a natural byproduct of model fitting.
coev_ancestral_states( object, variables = NULL, nodes = "internal", tree_id = NULL, scale = "latent", summary = TRUE, prob = 0.95 )coev_ancestral_states( object, variables = NULL, nodes = "internal", tree_id = NULL, scale = "latent", summary = TRUE, prob = 0.95 )
object |
An object of class |
variables |
(optional) A character vector of variable names to include.
If |
nodes |
Which nodes to include. Either |
tree_id |
(optional) An integer indicating which tree to use when the
model was fit with a |
scale |
Character string, either |
summary |
Logical. If |
prob |
A single numeric value between 0 and 1 indicating the desired probability mass for the credible interval. Default is 0.95. |
If summary = TRUE, a long-format data frame (tibble) with
columns:
Integer node ID in the reference tree
Character variable name
Only present when scale = "response". For
ordinal variables, the category label ("cat_1",
"cat_2", ...). NA for non-ordinal variables.
Posterior median
Lower bound of the credible interval
Upper bound of the credible interval
The data frame has attributes ref_tree (the phylo object used),
prob, and scale.
If summary = FALSE, a list with elements:
A 3D array (draws x nodes x variables)
The reference phylo object
Integer vector of node IDs (matching dim 2 of draws)
Character vector of variable names
coev_fit, coev_plot_trait_values
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, chains = 4, parallel_chains = 4, seed = 1 ) # extract ancestral states (latent scale, internal nodes, summary) asr <- coev_ancestral_states(fit) # extract all nodes including tips asr_all <- coev_ancestral_states(fit, nodes = "all") # extract on response scale asr_resp <- coev_ancestral_states(fit, scale = "response") # get raw posterior draws asr_draws <- coev_ancestral_states(fit, summary = FALSE) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, chains = 4, parallel_chains = 4, seed = 1 ) # extract ancestral states (latent scale, internal nodes, summary) asr <- coev_ancestral_states(fit) # extract all nodes including tips asr_all <- coev_ancestral_states(fit, nodes = "all") # extract on response scale asr_resp <- coev_ancestral_states(fit, scale = "response") # get raw posterior draws asr_draws <- coev_ancestral_states(fit, summary = FALSE) ## End(Not run)
coevfit objectCalculate from a fitted coevfit object.
is defined as the difference in the equilibrium value for
a "response" trait that results from a standardised increase in the value of
another "predictor" trait. This value can be used to assess contingencies
and directionality between variables in the coevolutionary process.
coev_calculate_delta_theta(object, response, predictor)coev_calculate_delta_theta(object, response, predictor)
object |
An object of class |
response |
A character string of length one equal to one of the coevolving variables in the model (strictly case-sensitive) |
predictor |
A character string of length one equal to one of the coevolving variables in the model (strictly case-sensitive) |
This function calculates , which is defined as the
difference in the equilibrium value for a "response" trait that results
from a standardised increase in the value of another "predictor" trait. The
function first calculates the equilibrium trait value for the response
trait when the predictor trait is held at its empirical median value (the
coev_calculate_theta function is used for this purpose, see
help(coev_calculate_theta) for further details). The function then
calculates the equilibrium trait value for the response variable after
increasing the predictor trait from its median by one median absolute
deviation. The function then returns the posterior difference between these
values. The resulting samples can be used to infer
whether increases in one trait have a positive or negative selective effect
on another trait in the model.
Posterior samples in the draws_array format
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
coev_calculate_delta_theta,
coev_plot_delta_theta
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # calculate delta theta coev_calculate_delta_theta( object = fit, response = "political_authority", predictor = "religious_authority" ) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # calculate delta theta coev_calculate_delta_theta( object = fit, response = "political_authority", predictor = "religious_authority" ) ## End(Not run)
coevfit objectCalculate equilibrium trait values for one or more traits given
a set of intervention values for other traits from a fitted coevfit
object.
coev_calculate_theta(object, intervention_values = NULL)coev_calculate_theta(object, intervention_values = NULL)
object |
An object of class |
intervention_values |
Either |
The equilibrium trait values for freely evolving traits
are calculated using the following formula:
If we hold some variables constant at some value(s) (denoted
) and let others evolve freely (denoted ), we
can partition the parameters as follows:
: selection coefficients to/from the free
variables
: selection coefficients to the free variables
from the held variables
: continuous time intercepts for the free
variables
We can then calculate the equilibrium values for the free variables:
With the overall equilibrium vector being a mix of the free equilibria and the held values:
Posterior samples in matrix format
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
coev_calculate_delta_theta,
coev_plot_delta_theta
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # calculate theta with no interventions coev_calculate_theta( object = fit ) # calculate theta given intervention values coev_calculate_theta( object = fit, intervention_values = list( political_authority = NA, religious_authority = 0 ) ) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # calculate theta with no interventions coev_calculate_theta( object = fit ) # calculate theta given intervention values coev_calculate_theta( object = fit, intervention_values = list( political_authority = NA, religious_authority = 0 ) ) ## End(Not run)
Fit Bayesian dynamic coevolutionary models in Stan for full Bayesian inference. The model allows users to assess causal directionality (X -> Y vs. Y -> X) and contingencies (X, then Y) in evolution. Several data types are supported, including binary, ordinal, count, continuous, and positive real variables. The model can additionally account for missing data, repeated observations, and controls for spatial proximity. Model fit can be assessed and compared with posterior predictive checks and cross-validation.
coev_fit( data, variables, id, tree, effects_mat = NULL, complete_cases = FALSE, lon_lat = NULL, dist_k = NA, dist_cov = "exp_quad", measurement_error = NULL, prior = NULL, scale = TRUE, estimate_correlated_drift = TRUE, estimate_residual = TRUE, log_lik = FALSE, prior_only = FALSE, adapt_delta = 0.95, nuts_sampler = "stan", backend = deprecated(), dist_mat = deprecated(), ... )coev_fit( data, variables, id, tree, effects_mat = NULL, complete_cases = FALSE, lon_lat = NULL, dist_k = NA, dist_cov = "exp_quad", measurement_error = NULL, prior = NULL, scale = TRUE, estimate_correlated_drift = TRUE, estimate_residual = TRUE, log_lik = FALSE, prior_only = FALSE, adapt_delta = 0.95, nuts_sampler = "stan", backend = deprecated(), dist_mat = deprecated(), ... )
data |
An object of class |
variables |
A named list identifying variables that should coevolve in
the model and their associated response distributions as character strings
(e.g. |
id |
A character of length one identifying the variable in the data that links rows to tips on the phylogeny (strictly case-sensitive). Must refer to a valid column name in the data. The id column must exactly match the tip labels in the phylogeny. |
tree |
A phylogenetic tree object of class |
effects_mat |
(optional) A boolean matrix with row and column names exactly matching the variables declared for the model. If not specified, all cross-lagged effects will be estimated in the model. If specified, the model will only estimate cross-lagged effects where cells in the matrix are TRUE and will ignore cross-lagged effects where cells in the matrix are FALSE. In the matrix, columns represent predictor variables and rows represent outcome variables. All autoregressive effects (e.g., X -> X) must be TRUE in the matrix. |
complete_cases |
(optional) Logical. If |
lon_lat |
(optional) A |
dist_k |
An integer of length one specifying the number of basis
functions for computing Hilbert-space approximate Gaussian Processes over
locations. If |
dist_cov |
A string of length one specifying the covariance kernel used
for Gaussian Processes over locations (strictly case-sensitive). Currently
supported are |
measurement_error |
(optional) A named list of coevolving variables and
their associated columns in the dataset containing standard errors. Only
valid for normally-distributed variables. For example, if we declare
|
prior |
(optional) A named list of priors for the model. If not
specified, the model uses default priors (see |
scale |
Logical. If |
estimate_correlated_drift |
Logical. If |
estimate_residual |
Logical. If |
log_lik |
Logical. Set to |
prior_only |
Logical. If |
adapt_delta |
Target acceptance probability for the
NUTS sampler (default |
nuts_sampler |
Which NUTS implementation to use.
|
backend |
Deprecated. Use the |
dist_mat |
Deprecated. Use the |
... |
Additional arguments. For
|
The coev_fit function generates the Stan code for the model,
generates the data list, and then compiles and fits the model using the
cmdstanr package.
Fit a Bayesian dynamic coevolutionary model in Stan. A general
overview is provided in the vignette vignette("coevolve")
Available response distributions
Variables that should coevolve in the model are declared in the
variables argument, using a named list with associated response
distributions. For example: list(x = "bernoulli_logit", y =
"ordered_logistic"). Currently, the only supported response distributions
are bernoulli_logit, ordered_logistic,
poisson_softplus, negative_binomial_softplus, normal,
and gamma_log.
Default prior distributions
If priors are not explicitly declared by the user, default priors are used. Default priors were chosen to be weakly regularising, which improves model fitting and conservatism in parameter estimates. Default priors for Stan parameters are as follows:
A_diag (autoregressive effects) = std_normal()
A_offdiag (cross effects) = std_normal()
L_R (Cholesky factor for drift matrix) =
lkj_corr_cholesky(4)
Q_sigma (drift std. dev. parameters) = std_normal()
b (continuous time intercepts) = std_normal()
eta_anc (trait ancestral states) = std_normal()
c (ordinal cutpoints) = normal(0, 2)
shape (shape parameters for gamma distributions) =
gamma(0.01, 0.01)
sigma_dist (sigma for Gaussian process over locations) =
exponential(1)
rho_dist (rho for Gaussian process over locations) =
exponential(5)
sigma_residual (residual standard deviations) =
exponential(1)
L_residual (Cholesky factor for residual correlations) =
lkj_corr_cholesky(4)
The default prior for phi (the overdispersion parameter for the
negative-binomial distribution) is scaled automatically based on the
variance of the data.
We recommend that users assess the suitability of these default priors by
fitting the model with prior_only = TRUE and then plotting prior
predictive checks for all variables using the
coev_plot_predictive_check() function.
Handling missing data
In order to retain the most information, the coev_fit() function
automatically imputes all missing values. To turn off this behaviour and
exclude taxa with missing data, set complete_cases = FALSE.
Dealing with repeated observations
If taxa appear in the dataset multiple times (i.e., there are repeated
observations), the model will automatically estimate residual standard
deviations and residual correlations that capture the within-taxa variation
that is not due to the coevolutionary process. To turn off this behaviour,
set estimate_residual = FALSE.
We do not recommend modelling residual standard deviations in cases where repeated observations are present for some traits but not others, as there will be no within-species variance for traits without repeated observations.
Note that models with repeated observations for mixtures of continuous and non-continuous traits are currently considered experimental and should be treated with caution.
Incorporating measurement error
If any normally-distributed coevolving variables are measured with error,
the user can pass standard errors for one or more of these variables into
the model with the measurement_error argument.
Controlling for spatial location
If users declare longitude and latitude values with the lon_lat
argument, the model will include several Gaussian processes (one per
coevolving variable) over spatial locations.
Fitted model of class coevfit
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
coev_make_stancode, coev_make_standata
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print model summary summary(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print model summary summary(fit) ## End(Not run)
Make the Stan code for the Bayesian dynamic coevolutionary model. Stan code is generated, checked for syntactical errors, and then returned as a character string.
coev_make_stancode( data, variables, id, tree, effects_mat = NULL, complete_cases = FALSE, lon_lat = NULL, dist_k = NA, dist_cov = "exp_quad", measurement_error = NULL, prior = NULL, scale = TRUE, estimate_correlated_drift = TRUE, estimate_residual = TRUE, log_lik = FALSE, prior_only = FALSE, dist_mat = deprecated() )coev_make_stancode( data, variables, id, tree, effects_mat = NULL, complete_cases = FALSE, lon_lat = NULL, dist_k = NA, dist_cov = "exp_quad", measurement_error = NULL, prior = NULL, scale = TRUE, estimate_correlated_drift = TRUE, estimate_residual = TRUE, log_lik = FALSE, prior_only = FALSE, dist_mat = deprecated() )
data |
An object of class |
variables |
A named list identifying variables that should coevolve in
the model and their associated response distributions as character strings
(e.g. |
id |
A character of length one identifying the variable in the data that links rows to tips on the phylogeny (strictly case-sensitive). Must refer to a valid column name in the data. The id column must exactly match the tip labels in the phylogeny. |
tree |
A phylogenetic tree object of class |
effects_mat |
(optional) A boolean matrix with row and column names exactly matching the variables declared for the model. If not specified, all cross-lagged effects will be estimated in the model. If specified, the model will only estimate cross-lagged effects where cells in the matrix are TRUE and will ignore cross-lagged effects where cells in the matrix are FALSE. In the matrix, columns represent predictor variables and rows represent outcome variables. All autoregressive effects (e.g., X -> X) must be TRUE in the matrix. |
complete_cases |
(optional) Logical. If |
lon_lat |
(optional) A |
dist_k |
An integer of length one specifying the number of basis
functions for computing Hilbert-space approximate Gaussian Processes over
locations. If |
dist_cov |
A string of length one specifying the covariance kernel used
for Gaussian Processes over locations (strictly case-sensitive). Currently
supported are |
measurement_error |
(optional) A named list of coevolving variables and
their associated columns in the dataset containing standard errors. Only
valid for normally-distributed variables. For example, if we declare
|
prior |
(optional) A named list of priors for the model. If not
specified, the model uses default priors (see |
scale |
Logical. If |
estimate_correlated_drift |
Logical. If
drift matrix (i.e., correlated
drift). If
drift matrix are set to zero. |
estimate_residual |
Logical. If |
log_lik |
Logical. Set to |
prior_only |
Logical. If |
dist_mat |
For further details, see help(coev_fit)
A character string containing the Stan code to fit the dynamic coevolutionary model
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
# make stan code stan_code <- coev_make_stancode( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny ) # include effects matrix effects_mat <- matrix( c(TRUE, TRUE, FALSE, TRUE), nrow = 2, dimnames = list( c("political_authority", "religious_authority"), c("political_authority", "religious_authority") ) ) stan_code <- coev_make_stancode( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, effects_mat = effects_mat ) # include longitude/latitude values stan_code <- coev_make_stancode( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, lon_lat = authority$coordinates ) # include measurement error d <- authority$data d$x <- rnorm(nrow(d)) d$y <- rnorm(nrow(d)) d$x_std_err <- rexp(nrow(d)) d$y_std_err <- rexp(nrow(d)) stan_code <- coev_make_stancode( data = d, variables = list( x = "normal", y = "normal" ), id = "language", tree = authority$phylogeny, measurement_error = list( x = "x_std_err", y = "y_std_err" ) ) # set manual priors stan_code <- coev_make_stancode( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, prior = list(A_offdiag = "normal(0, 2)") )# make stan code stan_code <- coev_make_stancode( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny ) # include effects matrix effects_mat <- matrix( c(TRUE, TRUE, FALSE, TRUE), nrow = 2, dimnames = list( c("political_authority", "religious_authority"), c("political_authority", "religious_authority") ) ) stan_code <- coev_make_stancode( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, effects_mat = effects_mat ) # include longitude/latitude values stan_code <- coev_make_stancode( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, lon_lat = authority$coordinates ) # include measurement error d <- authority$data d$x <- rnorm(nrow(d)) d$y <- rnorm(nrow(d)) d$x_std_err <- rexp(nrow(d)) d$y_std_err <- rexp(nrow(d)) stan_code <- coev_make_stancode( data = d, variables = list( x = "normal", y = "normal" ), id = "language", tree = authority$phylogeny, measurement_error = list( x = "x_std_err", y = "y_std_err" ) ) # set manual priors stan_code <- coev_make_stancode( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, prior = list(A_offdiag = "normal(0, 2)") )
Make the data list for the Stan model. The function takes a dataset, phylogeny, and a set of variables and performs the necessary computations (e.g., cutting up the tree into segments, computing branch lengths, determining parent and child nodes) for the Stan model.
coev_make_standata( data, variables, id, tree, effects_mat = NULL, complete_cases = FALSE, lon_lat = NULL, dist_k = NA, dist_cov = "exp_quad", measurement_error = NULL, prior = NULL, scale = TRUE, estimate_correlated_drift = TRUE, estimate_residual = TRUE, log_lik = FALSE, prior_only = FALSE, dist_mat = deprecated() )coev_make_standata( data, variables, id, tree, effects_mat = NULL, complete_cases = FALSE, lon_lat = NULL, dist_k = NA, dist_cov = "exp_quad", measurement_error = NULL, prior = NULL, scale = TRUE, estimate_correlated_drift = TRUE, estimate_residual = TRUE, log_lik = FALSE, prior_only = FALSE, dist_mat = deprecated() )
data |
An object of class |
variables |
A named list identifying variables that should coevolve in
the model and their associated response distributions as character strings
(e.g. |
id |
A character of length one identifying the variable in the data that links rows to tips on the phylogeny (strictly case-sensitive). Must refer to a valid column name in the data. The id column must exactly match the tip labels in the phylogeny. |
tree |
A phylogenetic tree object of class |
effects_mat |
(optional) A boolean matrix with row and column names exactly matching the variables declared for the model. If not specified, all cross-lagged effects will be estimated in the model. If specified, the model will only estimate cross-lagged effects where cells in the matrix are TRUE and will ignore cross-lagged effects where cells in the matrix are FALSE. In the matrix, columns represent predictor variables and rows represent outcome variables. All autoregressive effects (e.g., X -> X) must be TRUE in the matrix. |
complete_cases |
(optional) Logical. If |
lon_lat |
(optional) A |
dist_k |
An integer of length one specifying the number of basis
functions for computing Hilbert-space approximate Gaussian Processes over
locations. If |
dist_cov |
A string of length one specifying the covariance kernel used
for Gaussian Processes over locations (case-sensitive). Currently supported
are |
measurement_error |
(optional) A named list of coevolving variables and
their associated columns in the dataset containing standard errors. Only
valid for normally-distributed variables. For example, if we declare
|
prior |
(optional) A named list of priors for the model. If not
specified, the model uses default priors (see |
scale |
Logical. If |
estimate_correlated_drift |
Logical. If
drift matrix (i.e., correlated
drift). If
drift matrix are set to zero. |
estimate_residual |
Logical. If |
log_lik |
Logical. Set to |
prior_only |
Logical. If |
dist_mat |
For further details, see help(coev_fit)
A list containing the data for fitting the dynamic coevolutionary model in Stan
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
# make stan data stan_data <- coev_make_standata( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny ) # include effects matrix effects_mat <- matrix( c(TRUE, TRUE, FALSE, TRUE), nrow = 2, dimnames = list( c("political_authority", "religious_authority"), c("political_authority", "religious_authority") ) ) stan_data <- coev_make_standata( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, effects_mat = effects_mat ) # include longitude/latitude values stan_data <- coev_make_standata( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, lon_lat = authority$coordinates ) # include measurement error d <- authority$data d$x <- rnorm(nrow(d)) d$y <- rnorm(nrow(d)) d$x_std_err <- rexp(nrow(d)) d$y_std_err <- rexp(nrow(d)) stan_data <- coev_make_standata( data = d, variables = list( x = "normal", y = "normal" ), id = "language", tree = authority$phylogeny, measurement_error = list( x = "x_std_err", y = "y_std_err" ) ) # set manual priors stan_data <- coev_make_standata( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, prior = list(A_offdiag = "normal(0, 2)") )# make stan data stan_data <- coev_make_standata( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny ) # include effects matrix effects_mat <- matrix( c(TRUE, TRUE, FALSE, TRUE), nrow = 2, dimnames = list( c("political_authority", "religious_authority"), c("political_authority", "religious_authority") ) ) stan_data <- coev_make_standata( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, effects_mat = effects_mat ) # include longitude/latitude values stan_data <- coev_make_standata( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, lon_lat = authority$coordinates ) # include measurement error d <- authority$data d$x <- rnorm(nrow(d)) d$y <- rnorm(nrow(d)) d$x_std_err <- rexp(nrow(d)) d$y_std_err <- rexp(nrow(d)) stan_data <- coev_make_standata( data = d, variables = list( x = "normal", y = "normal" ), id = "language", tree = authority$phylogeny, measurement_error = list( x = "x_std_err", y = "y_std_err" ) ) # set manual priors stan_data <- coev_make_standata( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, prior = list(A_offdiag = "normal(0, 2)") )
coevfit objectPlot delta theta values for all trait pairs from a fitted coevfit
object. This plot can be used to visually assess contingencies and
directionality between different variables in the coevolutionary process.
coev_plot_delta_theta( object, variables = NULL, prob = 0.66, prob_outer = 0.95, limits = NULL )coev_plot_delta_theta( object, variables = NULL, prob = 0.66, prob_outer = 0.95, limits = NULL )
object |
An object of class |
variables |
If NULL (default), the plot includes all coevolving variables from the model. Otherwise, a character vector of length >= 2 declaring the variables to be included in the plot. |
prob |
Probability mass to include in the inner interval. Default is 0.66 (66% interval). |
prob_outer |
Probability mass to include in the outer interval. Default is 0.95 (95% interval). |
limits |
If NULL (default), limits are scaled automatically to include all posterior samples. Otherwise, a numeric vector of length 2 specifying the lower and upper limits for the x-axis. |
This function repeatedly uses the
coev_calculate_delta_theta function under the hood to
generate a pairs plot of for all variables in the model.
For more details on the definition and calculation of ,
see help(coev_calculate_delta_theta). Note that often the posterior
distribution for has long tails, meaning that the
distribution for different traits can be difficult to visualise in a single
pairs plot. If this plot does not produce satisfactory visualisations, the
user should either specify narrower limits for the x-axis or use the
coev_calculate_delta_theta function to create plots manually.
A ggplot object
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
coev_calculate_delta_theta,
coev_calculate_theta
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # plot delta theta values for all effects coev_plot_delta_theta(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # plot delta theta values for all effects coev_plot_delta_theta(fit) ## End(Not run)
coevfit
objectPlot a flowfield of the expected evolutionary dynamics from a fitted
coevfit object, with help from the phaseR package.
coev_plot_flowfield( object, var1, var2, nullclines = FALSE, limits = c(-2.5, 2.5) )coev_plot_flowfield( object, var1, var2, nullclines = FALSE, limits = c(-2.5, 2.5) )
object |
An object of class |
var1 |
A character string of length one equal to one of the coevolving variables in the model (strictly case-sensitive) |
var2 |
A character string of length one equal to one of the coevolving variables in the model (strictly case-sensitive) |
nullclines |
Logical (defaults to FALSE); whether to show coloured nullclines to indicate where each variable is at equilibrium, depending on the state of the other |
limits |
A numeric vector of length 2 (defaults to |
The flowfield visualises the change in two coevolving traits depending on their current states, with the direction and strength of change depicting with the direction and size of arrows. If nullclines are included, they represent the parameter combinations where each trait is at equilibrium, depending on the state of the other trait.
If three or more traits were included in the model, other traits are held at their median values during the computations. Note that flowfield plots can potentially produce misleading pictures of coevolutionary dynamics when other traits are held constant in models with three or more traits.
If the plot does not look right, the user might try zooming out from the default parameter space by setting wider limits. For some variables (e.g., continuous and count variables), the default limits may not be suitable.
A flowfield plot drawn directly to the device
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # plot flow field coev_plot_flowfield( object = fit, var1 = "political_authority", var2 = "religious_authority" ) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # plot flow field coev_plot_flowfield( object = fit, var1 = "political_authority", var2 = "religious_authority" ) ## End(Not run)
coevfit
objectThis function plots a predicted coevolutionary time series using the
estimated parameters from a fitted coevfit model. By default, the
plot uses the posterior ancestral states estimated by the model as the
starting values, but users can also set their own starting values for
traits. Plots can be generated with or without stochastic drift. For more
details on the underlying predictive function, see
help(coev_pred_series).
coev_plot_pred_series(object, prob = 0.95, ...)coev_plot_pred_series(object, prob = 0.95, ...)
object |
An object of class |
prob |
A value between 0 and 1 indicating the desired probability to be covered by the uncertainty intervals. The default is 0.95. |
... |
Additional arguments passed to |
A ggplot object
Scott Claessens [email protected], Erik Ringen [email protected]
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # simulated trait co-evolution coev_plot_pred_series( object = fit, stochastic = TRUE ) # expected trait co-evolution, no drift coev_plot_pred_series( object = fit, stochastic = FALSE, eta_anc = list(political_authority = -2, religious_authority = 1.5) ) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # simulated trait co-evolution coev_plot_pred_series( object = fit, stochastic = TRUE ) # expected trait co-evolution, no drift coev_plot_pred_series( object = fit, stochastic = FALSE, eta_anc = list(political_authority = -2, religious_authority = 1.5) ) ## End(Not run)
coevfit objectPlot posterior (or prior) predictive checks for variables from a fitted
coevfit object, with help from the bayesplot package.
coev_plot_predictive_check( object, variables = NULL, ndraws = NULL, tree_id = NULL )coev_plot_predictive_check( object, variables = NULL, ndraws = NULL, tree_id = NULL )
object |
An object of class |
variables |
If NULL (default), the function returns a list of plots for all coevolving variables from the model. Otherwise, a character vector declaring the variables to be included in the list of plots. |
ndraws |
An integer indicating the number of draws to return. The default and maximum number of draws is the size of the posterior sample. |
tree_id |
An integer indicating the tree ID to use when making
posterior predictions. Set to |
A list of ggplot objects
Scott Claessens [email protected], Erik Ringen [email protected]
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # plot predictive checks for all variables coev_plot_predictive_check(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # plot predictive checks for all variables coev_plot_predictive_check(fit) ## End(Not run)
coevfit objectPlot a heatmap of the selection gradient for two variables from a fitted
coevfit object.
coev_plot_selection_gradient( object, var1, var2, contour = FALSE, limits = c(-2.5, 2.5) )coev_plot_selection_gradient( object, var1, var2, contour = FALSE, limits = c(-2.5, 2.5) )
object |
An object of class |
var1 |
A character string of length one equal to one of the coevolving variables in the model (strictly case-sensitive) |
var2 |
A character string of length one equal to one of the coevolving variables in the model (strictly case-sensitive) |
contour |
Logical (defaults to FALSE); whether to show white contour lines to indicate where selection is stronger than drift |
limits |
A numeric vector of length 2 (defaults to |
The selection gradient is operationalised as the ratio of the
change in a trait due to deterministic selection to
the change in a trait due to stochastic drift . Values
between -1 and 1 indicate parameter space where the change due to
drift is greater than change due to selection on the trait. Conversely,
values greater than 1 (or less than -1) indicate parameter space where
positive (or negative) selection is stronger than drift.
If three or more traits were included in the model, other traits are held at their median values during the computations. Note that selection gradient plots can potentially produce misleading pictures of coevolutionary dynamics when other traits are held constant in models with three or more traits.
If the plot does not look right, the user might try zooming out from the default parameter space by setting wider limits. For some variables (e.g., continuous and count variables), the default limits may not be suitable.
A ggplot object
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # plot selection gradient coev_plot_selection_gradient( object = fit, var1 = "political_authority", var2 = "religious_authority" ) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # plot selection gradient coev_plot_selection_gradient( object = fit, var1 = "political_authority", var2 = "religious_authority" ) ## End(Not run)
coevfit objectProduce a pairs plot of the estimated trait values for taxa from a fitted
coevfit object. The plot includes scatterplot(s) of median estimated
trait values, heatmap(s) of median estimated trait values, and density plots
of the marginal distributions for each variable with associated posterior
uncertainty.
coev_plot_trait_values( object, variables = NULL, ndraws = 50, tree_id = NULL, xlim = NULL, ylim = NULL )coev_plot_trait_values( object, variables = NULL, ndraws = 50, tree_id = NULL, xlim = NULL, ylim = NULL )
object |
An object of class |
variables |
If NULL (default), the function returns a pairs plot including all coevolving variables from the model. Otherwise, a character vector declaring the variables to be included. |
ndraws |
An integer indicating the number of draws to return in the density plots on the diagonal. The default and maximum number of draws is the size of the posterior sample. |
tree_id |
An integer indicating the tree ID to use when making
posterior predictions. Set to |
xlim |
Limits for the x-axis. If |
ylim |
Limits for the y-axis. If |
A patchwork of ggplot objects
Scott Claessens [email protected], Erik Ringen [email protected]
Ringen, E., Martin, J. S., & Jaeggi, A. (2021). Novel phylogenetic methods
reveal that resource-use intensification drives the evolution of "complex"
societies. EcoEvoRXiv. doi:10.32942/osf.io/wfp95
Sheehan, O., Watts, J., Gray, R. D., Bulbulia, J., Claessens, S., Ringen,
E. J., & Atkinson, Q. D. (2023). Coevolution of religious and political
authority in Austronesian societies. Nature Human Behaviour,
7(1), 38-45. 10.1038/s41562-022-01471-y
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # pairs plot of trait values coev_plot_trait_values(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # pairs plot of trait values coev_plot_trait_values(fit) ## End(Not run)
coevfit objectThis function produces predicted values of traits over a time series, given
the estimated parameters for a coevfit model. This function is used
under the hood by the plotting function coev_pred_series.
coev_pred_series( object, eta_anc = NULL, intervention_values = NULL, tmax = 1, ntimes = 30, ndraws = NULL, stochastic = FALSE )coev_pred_series( object, eta_anc = NULL, intervention_values = NULL, tmax = 1, ntimes = 30, ndraws = NULL, stochastic = FALSE )
object |
An object of class |
eta_anc |
If |
intervention_values |
Either |
tmax |
A positive number indicating the total duration of time for which to predict. Set to 1 by default, corresponding to the entire time depth of the original phylogenetic tree(s). |
ntimes |
A positive integer indicating the total number of discrete time steps over which to make predictions. Each step corresponds to a time difference of dt = tmax/ntimes. Set to 30 by default. |
ndraws |
An integer indicating the number of draws to return. The default and maximum number of draws is the size of the posterior sample. |
stochastic |
Logical (defaults to |
An [ndraw, ntimes, nvariables] array of predicted
values
Scott Claessens [email protected], Erik Ringen [email protected]
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # simulate trait co-evolution sims <- coev_pred_series( object = fit, stochastic = TRUE ) # expected trait co-evolution, no drift epreds <- coev_pred_series( object = fit, stochastic = FALSE, eta_anc = list(political_authority = -2, religious_authority = 1.5) ) # expected trait co-evolution under intervention, no drift epreds_intervention <- coev_pred_series( object = fit, stochastic = FALSE, intervention_values = list(political_authority = NA, religious_authority = 1.5) ) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # simulate trait co-evolution sims <- coev_pred_series( object = fit, stochastic = TRUE ) # expected trait co-evolution, no drift epreds <- coev_pred_series( object = fit, stochastic = FALSE, eta_anc = list(political_authority = -2, religious_authority = 1.5) ) # expected trait co-evolution under intervention, no drift epreds_intervention <- coev_pred_series( object = fit, stochastic = FALSE, intervention_values = list(political_authority = NA, religious_authority = 1.5) ) ## End(Not run)
This function simulates the coevolution of multiple continuous variables in discrete time steps following a simple VAR(1) autoregressive model. Users set the sample size, the variable names, the strength of selection and drift, and the probability of a speciation event in a given time step. The function returns a phylogeny, the results of the simulation run, and a dataset of contemporary trait values.
coev_simulate_coevolution( n, variables, selection_matrix, drift, prob_split, intercepts = NULL, ancestral_states = NULL )coev_simulate_coevolution( n, variables, selection_matrix, drift, prob_split, intercepts = NULL, ancestral_states = NULL )
n |
Number of data points in the resulting data frame. |
variables |
A character vector of variable names (e.g.,
|
selection_matrix |
A numeric matrix determining the strength of selection between variables. The matrix must have a number of rows and columns equal to the number of variables and its row and column names must contain all specified variables. Each cell determines the strength of selection from the column variable to the row variable. For example, the cell on the "x" column and the "x" row indicates how much previous values of x influence future values of x (autocorrelation). By contrast, the cell on the "x" column and the "y" row indicates how much previous values of x influence future values of y (cross-lagged effect). |
drift |
A named numeric vector specifying the strength of drift for different variables. Names must include all specified variables. |
prob_split |
A numeric probability of a species split in any given timestep. |
intercepts |
Intercepts for the VAR(1) model. If NULL (default), intercepts are set to zero for all variables. Otherwise, a named numeric vector specifying the intercepts for different variables. Names must include all specified variables. |
ancestral_states |
Ancestral states for different variables. If NULL (default), ancestral states are set to zero for all variables. Otherwise, a named numeric vector specifying the ancestral states for different variables. Names must include all specified variables. |
The model underlying this simulation is a simple VAR(1) autoregressive model, where values of all variables at the previous timestep predict values at the current timestep. In the case of two variables, the model is as follows:
where represents the intercepts, represents the
selection matrix, and represents the vector of drift
parameters. With some probability , a speciation event creates two
independent evolutionary branches. This simulation continues until the
intended sample size of species has been reached. Note: this VAR(1) model
is not the same as the generalized dynamic phylogenetic model that is
estimated by the coev_fit() function (see the introductory vignette for
mathematical details of generalized dynamic phylogenetic models).
List with dataset at final timestep (data), full simulation log (simulation), and pruned phylogenetic tree (tree)
Scott Claessens [email protected], Erik Ringen [email protected]
# simulate coevolution of x and y n <- 100 variables <- c("x", "y") # x -> y but not vice versa selection_matrix <- matrix( c( 0.95, 0.00, 0.80, 0.95 ), nrow = 2, byrow = TRUE, dimnames = list(variables, variables) ) drift <- c("x" = 0.05, "y" = 0.05) prob_split <- 0.05 # run simulation with default parameters coev_simulate_coevolution( n, variables, selection_matrix, drift, prob_split ) # set intercepts manually coev_simulate_coevolution( n, variables, selection_matrix, drift, prob_split, intercepts = c("x" = 1, "y" = -1) ) # set ancestral states manually coev_simulate_coevolution( n, variables, selection_matrix, drift, prob_split, ancestral_states = c("x" = 1, "y" = -1) )# simulate coevolution of x and y n <- 100 variables <- c("x", "y") # x -> y but not vice versa selection_matrix <- matrix( c( 0.95, 0.00, 0.80, 0.95 ), nrow = 2, byrow = TRUE, dimnames = list(variables, variables) ) drift <- c("x" = 0.05, "y" = 0.05) prob_split <- 0.05 # run simulation with default parameters coev_simulate_coevolution( n, variables, selection_matrix, drift, prob_split ) # set intercepts manually coev_simulate_coevolution( n, variables, selection_matrix, drift, prob_split, intercepts = c("x" = 1, "y" = -1) ) # set ancestral states manually coev_simulate_coevolution( n, variables, selection_matrix, drift, prob_split, ancestral_states = c("x" = 1, "y" = -1) )
Internal S3 method. Extracts draws from a jax_fit object, compatible with cmdstanr's draws() method.
## S3 method for class 'jax_fit' draws(x, variables = NULL, ...)## S3 method for class 'jax_fit' draws(x, variables = NULL, ...)
x |
A jax_fit object. |
variables |
Character vector of variable names to extract. |
... |
Additional arguments (ignored). |
A draws_array object.
TRUETRUE
Internal S3 method. Extracts draws from a nutpie_fit object, compatible with cmdstanr's draws() method.
## S3 method for class 'nutpie_fit' draws(x, variables = NULL, ...)## S3 method for class 'nutpie_fit' draws(x, variables = NULL, ...)
x |
A nutpie_fit object. |
variables |
Character vector of variable names to extract. If NULL, extracts all variables. |
... |
Additional arguments (currently ignored). |
A draws_array object.
TRUETRUE
coevfit objectExtract samples (draws) from a fitted coevfit object
extract_samples(object)extract_samples(object)
object |
An object of class |
Samples in 'rethinking' style list format
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # extract samples from fitted model extract_samples(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # extract samples from fitted model extract_samples(fit) ## End(Not run)
Internal S3 method. Extracts metadata from a jax_fit object, compatible with cmdstanr's metadata() method.
## S3 method for class 'jax_fit' metadata(x)## S3 method for class 'jax_fit' metadata(x)
x |
A jax_fit object. |
A list containing metadata.
TRUETRUE
Internal S3 method. Extracts metadata from a nutpie_fit object, compatible with cmdstanr's metadata() method.
## S3 method for class 'nutpie_fit' metadata(x)## S3 method for class 'nutpie_fit' metadata(x)
x |
A nutpie_fit object. |
A list containing metadata.
TRUETRUE
coevfit objectA pairs method that is customized for MCMC
output.
## S3 method for class 'coevfit' pairs(x, parameters = NULL, ...)## S3 method for class 'coevfit' pairs(x, parameters = NULL, ...)
x |
An object of class |
parameters |
If NULL (default), the function returns plots for the main parameters from the model (the selection matrix "A", the drift matrix "Q", and the continuous time intercepts "b"). Otherwise, a character vector declaring the parameters to plot (strictly case-sensitive). |
... |
Further arguments to be passed to
|
For a detailed description see
mcmc_pairs.
A matrix of output plots
Scott Claessens [email protected]
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print pairs plot pairs(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print pairs plot pairs(fit) ## End(Not run)
coevfit objectsTrace and density plots for coevfit objects
## S3 method for class 'coevfit' plot( x, parameters = NULL, combo = c("dens", "trace"), npars = 5, plot = TRUE, ... )## S3 method for class 'coevfit' plot( x, parameters = NULL, combo = c("dens", "trace"), npars = 5, plot = TRUE, ... )
x |
An object of class |
parameters |
If NULL (default), the function returns plots for the main parameters from the model (the selection matrix "A", the drift matrix "Q", and the continuous time intercepts "b"). Otherwise, a character vector declaring the parameters to plot (strictly case-sensitive). |
combo |
A character vector with at least two elements. Each element of
|
npars |
Number of parameters displayed per page (default = 5). |
plot |
Logical. If TRUE (default), plots are plotted in the active graphic device. If FALSE, plots are not plotted. |
... |
Not used. |
A list of ggplot objects
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print trace and density plots plot(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print trace and density plots plot(fit) ## End(Not run)
This dataset and associated phylogeny describes brain weights, body weights, dietary categories, social systems, mating systems, and group sizes for 143 primate species. These data were originally compiled in DeCasien et al. (2017). The phylogeny is a 50% majority rule consensus tree from the 10k Trees website.
primatesprimates
A list containing a dataset and an associated phylogeny. The phylogeny is a pruned consensus tree for 143 species of primate (excluding humans). The dataset is a data frame with 143 observations and 11 variables:
The primate species
The clade of the primate species
Average brain weight, in grams
Average body weight, in grams
A factor with four levels indicating whether the species' dietary category is folivore, frugivore, frugivore/folivore, or omnivore
Percentage of fruit in diet
A factor with four levels indicating whether the species' social system is solitary, pair-living, harem polygyny, or polygynandry
A factor with five levels indicating whether the species' mating system is spatial polygyny, monogamy, polyandry, harem polygyny, or polygynandry
Average group size
DeCasien, A. R., Williams, S. A., & Higham, J. P. (2017). Primate brain size is predicted by diet but not sociality. Nature Ecology & Evolution, 1(5), 0112.
Arnold, C., Matthews, L. J., & Nunn, C. L. (2010). The 10kTrees website: a new online resource for primate phylogeny. Evolutionary Anthropology, 19(3), 114-118.
https://10ktrees.nunn-lab.org/Primates/index.html
## Not run: # fit model to primates data m <- coev_fit( data = primates$data, variables = list( brain_weight = "lognormal", body_weight = "lognormal" ), id = "species", tree = primates$phylogeny, # arguments to cmdstanr::sample() parallel_chains = 4, seed = 1 ) # print model summary summary(m) # plot delta theta coev_plot_delta_theta(m) ## End(Not run)## Not run: # fit model to primates data m <- coev_fit( data = primates$data, variables = list( brain_weight = "lognormal", body_weight = "lognormal" ), id = "species", tree = primates$phylogeny, # arguments to cmdstanr::sample() parallel_chains = 4, seed = 1 ) # print model summary summary(m) # plot delta theta coev_plot_delta_theta(m) ## End(Not run)
coevfit objectPrint a summary of a fitted model represented by a coevfit object
## S3 method for class 'coevfit' print(x, digits = 2, ...)## S3 method for class 'coevfit' print(x, digits = 2, ...)
x |
An object of class |
digits |
The number of significant digits for printing out the summary; defaults to 2 |
... |
Additional arguments that would be passed
to method |
A printed summary of a coevfit model object
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print summary of model print(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print summary of model print(fit) ## End(Not run)
This example dataset and associated phylogeny are used as an example of repeated observations in phylogenetic modelling. The data are adapted from de Villemeruil & Nakagawa (2014) to include only the first twenty species.
repeatedrepeated
A list containing a dataset and an associated phylogeny. The dataset is a data frame with 100 observations and 3 variables:
The name of the species
An example continuous variable
An example continuous variable
de Villemeruil P. & Nakagawa, S. (2014). General quantitative genetic methods for comparative biology. In L. Garamszegi (Ed.), Modern phylogenetic comparative methods and their application in evolutionary biology: concepts and practice (pp. 287-303). Springer, New York.
## Not run: # fit model to repeated data m <- coev_fit( data = repeated$data, variables = list( x = "normal", y = "normal" ), id = "species", tree = repeated$phylogeny, # arguments to cmdstanr::sample() parallel_chains = 4, seed = 1 ) # print model summary summary(m) # plot delta theta coev_plot_delta_theta(m) ## End(Not run)## Not run: # fit model to repeated data m <- coev_fit( data = repeated$data, variables = list( x = "normal", y = "normal" ), id = "species", tree = repeated$phylogeny, # arguments to cmdstanr::sample() parallel_chains = 4, seed = 1 ) # print model summary summary(m) # plot delta theta coev_plot_delta_theta(m) ## End(Not run)
coevfit object to a fileA wrapper around saveRDS that saves a fitted
coevfit model object while ensuring that all posterior draws and
diagnostics are correctly saved by cmdstanr.
save_coevfit(object, file, ...)save_coevfit(object, file, ...)
object |
An object of class |
file |
A string declaring the path where the file should be saved |
... |
Other arguments to pass to |
An .RDS file containing the fitted coevfit model object
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # save model to .rds file save_coevfit(fit, file = "model.rds") ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # save model to .rds file save_coevfit(fit, file = "model.rds") ## End(Not run)
coevfit objectExpose the Stan code of a fitted model represented by a coevfit object
stancode(object)stancode(object)
object |
An object of class |
Printed Stan code
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # expose stan code stancode(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # expose stan code stancode(fit) ## End(Not run)
coevfit
objectExpose the Stan data list for a fitted model represented by a coevfit
object
standata(object)standata(object)
object |
An object of class |
Named list of data for Stan
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # expose stan data standata(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # expose stan data standata(fit) ## End(Not run)
coevfit objectCreate a summary of a fitted model represented by a coevfit object
## S3 method for class 'coevfit' summary(object, prob = 0.95, robust = FALSE, ...)## S3 method for class 'coevfit' summary(object, prob = 0.95, robust = FALSE, ...)
object |
An object of class |
prob |
A value between 0 and 1 indicating the desired probability to be covered by the uncertainty intervals. The default is 0.95. |
robust |
If |
... |
Other potential arguments |
The convergence diagnostics rhat, ess_bulk, and
ess_tail are described in detail in Vehtari et al. (2020).
List of class coevsummary
Aki Vehtari, Andrew Gelman, Daniel Simpson, Bob Carpenter, and Paul-Christian Bürkner (2020). Rank-normalization, folding, and localization: An improved R-hat for assessing convergence of MCMC. Bayesian Analysis. 1–28. dpi:10.1214/20-BA1221
## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print summary of model summary(fit) ## End(Not run)## Not run: # fit dynamic coevolutionary model fit <- coev_fit( data = authority$data, variables = list( political_authority = "ordered_logistic", religious_authority = "ordered_logistic" ), id = "language", tree = authority$phylogeny, # additional arguments for cmdstanr::sample() chains = 4, parallel_chains = 4, seed = 1 ) # print summary of model summary(fit) ## End(Not run)
Internal S3 method. Computes summary statistics from a jax_fit object, compatible with cmdstanr's summary() method. This method mimics cmdstanr's interface where summary() is called with named arguments where names are column names and values are function names or formulas.
## S3 method for class 'jax_fit' summary(object, variables = NULL, ...)## S3 method for class 'jax_fit' summary(object, variables = NULL, ...)
object |
A jax_fit object. |
variables |
Character vector of variable names to summarize. |
... |
Named summary spec arguments (cmdstanr style). |
A data.frame with summary statistics.
TRUETRUE
Internal S3 method. Computes summary statistics from a nutpie_fit object, compatible with cmdstanr's summary() method. This method mimics cmdstanr's interface where summary() is called with named arguments where names are column names and values are function names or formulas.
## S3 method for class 'nutpie_fit' summary(object, variables = NULL, ...)## S3 method for class 'nutpie_fit' summary(object, variables = NULL, ...)
object |
A nutpie_fit object. |
variables |
Character vector of variable names to summarize. If NULL, summarizes all variables. |
... |
Named arguments where names are output column names and values are function names (strings) or formulas for computing statistics. |
A data.frame with summary statistics, compatible with cmdstanr format.
TRUETRUE