| Title: | Bayesian Priors for Matrix Population Models |
|---|---|
| Description: | Provides functions to correct biased transition and fertility estimates in population projection matrices caused by small sample sizes. Small or short-term studies frequently produce structural zeros (biologically possible transitions never observed) and structural ones (transitions estimated at 100% survival, stasis, or mortality that are biologically implausible). Both distort matrix structure and bias estimates of population growth. Implements a multinomial-Dirichlet Bayesian prior for transition probabilities and a Gamma-Poisson prior for reproduction, allowing analysts to incorporate prior biological knowledge and regularise estimates from rare or unobserved events. Includes functions to compute marginal posterior credible intervals for all transition probabilities (transition_CrI()), visualise those intervals as point-range plots (plot_transition_CrI()), and display the full posterior beta density for each matrix entry (plot_transition_density()). Methods are described in Tremblay et al. (2021) <doi:10.1016/j.ecolmodel.2021.109526>. |
| Authors: | Raymond Tremblay [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-8588-4372>), Andrew Tyre [aut, cph] (ORCID: <https://orcid.org/0000-0001-9736-641X>), Maria-Eglee Perez [aut] (ORCID: <https://orcid.org/0000-0001-8641-8405>), Sasha Tenhumberg [ctb] |
| Maintainer: | Raymond Tremblay <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.0.5 |
| Built: | 2026-05-15 22:00:21 UTC |
| Source: | https://github.com/atiretoo/raretrans |
Provides functions to correct biased transition and fertility estimates in population projection matrices caused by small sample sizes. Small or short-term studies frequently produce structural zeros (biologically possible transitions never observed) and structural ones (transitions estimated at 100 Both distort matrix structure and bias estimates of population growth. Functions combine observed transition data with Bayesian prior beliefs to regularise estimates from rare or unobserved events.
Maintainer: Raymond Tremblay [email protected] (ORCID) [copyright holder]
Authors:
Raymond Tremblay [email protected] (ORCID) [copyright holder]
Andrew Tyre [email protected] (ORCID) [copyright holder]
Maria-Eglee Perez [email protected] (ORCID)
Other contributors:
Sasha Tenhumberg [contributor]
Useful links:
Report bugs at https://github.com/atiretoo/raretrans/issues
fill_fertility returns the expected value of the fertility
matrix combining observed recruits for one time step and a Gamma prior for each column.
fill_fertility( TF, N, alpha = 1e-05, beta = 1e-05, priorweight = -1, returnType = "F" )fill_fertility( TF, N, alpha = 1e-05, beta = 1e-05, priorweight = -1, returnType = "F" )
TF |
A list of two matrices, T and F, as ouput by |
N |
A vector of observed stage distribution. |
alpha |
A matrix of the prior parameter for each stage. Impossible stage combinations marked with NA_real_. |
beta |
A matrix of the prior parameter for each stage. Impossible stage combinations marked with NA_real_. |
priorweight |
total weight for each column of prior as a percentage of sample size or 1 if negative |
returnType |
A character vector describing the desired return value. Defaults to "F" the fertility matrix |
Assumes that only one stage reproduces ... needs generalizing.
The return value depends on parameter returnType.
A - the summed matrix "filled in" using a Gamma prior
F - just the filled in fertility matrix
ab - the posterior parameters alpha and beta as a list.
# Build a simple 3-stage TF list (transition + fertility matrices) T_mat <- matrix(c( 0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7 ), nrow = 3, ncol = 3) F_mat <- matrix(c( 0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Only adults (stage 3) reproduce; mark non-reproducing entries with NA alpha_mat <- matrix(c( NA, NA, 0.5, NA, NA, NA, NA, NA, NA ), nrow = 3, ncol = 3) beta_mat <- matrix(c( NA, NA, 1.0, NA, NA, NA, NA, NA, NA ), nrow = 3, ncol = 3) # Default: return filled fertility matrix F fill_fertility(TF, N, alpha = alpha_mat, beta = beta_mat) # Return the full population matrix A = T + F fill_fertility(TF, N, alpha = alpha_mat, beta = beta_mat, returnType = "A") # Return the posterior alpha and beta parameters fill_fertility(TF, N, alpha = alpha_mat, beta = beta_mat, returnType = "ab")# Build a simple 3-stage TF list (transition + fertility matrices) T_mat <- matrix(c( 0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7 ), nrow = 3, ncol = 3) F_mat <- matrix(c( 0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Only adults (stage 3) reproduce; mark non-reproducing entries with NA alpha_mat <- matrix(c( NA, NA, 0.5, NA, NA, NA, NA, NA, NA ), nrow = 3, ncol = 3) beta_mat <- matrix(c( NA, NA, 1.0, NA, NA, NA, NA, NA, NA ), nrow = 3, ncol = 3) # Default: return filled fertility matrix F fill_fertility(TF, N, alpha = alpha_mat, beta = beta_mat) # Return the full population matrix A = T + F fill_fertility(TF, N, alpha = alpha_mat, beta = beta_mat, returnType = "A") # Return the posterior alpha and beta parameters fill_fertility(TF, N, alpha = alpha_mat, beta = beta_mat, returnType = "ab")
fill_transition returns the expected value of the transition
matrix combining observed transitions for one time step and a prior
fill_transitions(TF, N, P = NULL, priorweight = -1, returnType = "T")fill_transitions(TF, N, P = NULL, priorweight = -1, returnType = "T")
TF |
A list of two matrices, T and F, as ouput by |
N |
A vector of observed transitions. |
P |
A matrix of the priors for each column. Defaults to uniform. |
priorweight |
total weight for each column of prior as a percentage of sample size or 1 if negative |
returnType |
A character vector describing the desired return value. Defaults to "T" the transition matrix. |
The return value depends on parameter returnType.
A - the summed matrix "filled in" using a dirichlet prior
T - just the filled in transition matrix
TN - the augmented matrix of fates – use in calculating the CI or for simulation
# Build a simple 3-stage TF list (transition + fertility matrices) T_mat <- matrix(c( 0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7 ), nrow = 3, ncol = 3) F_mat <- matrix(c( 0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Default: return filled transition matrix T fill_transitions(TF, N) # Return the full population matrix A = T + F fill_transitions(TF, N, returnType = "A") # Use a prior weight equal to the sample size fill_transitions(TF, N, priorweight = 1)# Build a simple 3-stage TF list (transition + fertility matrices) T_mat <- matrix(c( 0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7 ), nrow = 3, ncol = 3) F_mat <- matrix(c( 0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Default: return filled transition matrix T fill_transitions(TF, N) # Return the full population matrix A = T + F fill_transitions(TF, N, returnType = "A") # Use a prior weight equal to the sample size fill_transitions(TF, N, priorweight = 1)
Extract the number of individuals in each stage from a dataframe of transitions.
get_state_vector(transitions, stage = NULL, sort = NULL)get_state_vector(transitions, stage = NULL, sort = NULL)
transitions |
a dataframe of observations of individuals in different stages |
stage |
the name of the variable with the stage information |
sort |
a vector of stage names in the desired order. Default is the order of levels in stage. |
a vector of the counts of observations in each level of stage.
data("L_elto") # Extract one population at one census period onepop <- L_elto[L_elto$POPNUM == 250 & L_elto$year == 5, ] onepop$stage <- factor(onepop$stage, levels = c("p", "j", "a")) # Count individuals per stage in the order p, j, a get_state_vector(onepop, stage = "stage", sort = c("p", "j", "a"))data("L_elto") # Extract one population at one census period onepop <- L_elto[L_elto$POPNUM == 250 & L_elto$year == 5, ] onepop$stage <- factor(onepop$stage, levels = c("p", "j", "a")) # Count individuals per stage in the order p, j, a get_state_vector(onepop, stage = "stage", sort = c("p", "j", "a"))
Individual-level census data from multiple populations of the epiphytic orchid Lepanthes eltoroensis Stimson, a critically rare species endemic to Puerto Rico. Individuals were permanently marked and surveyed at 6-month intervals over 12 census periods (6 calendar years). Each row represents one individual observed at one census period.
data(L_elto)data(L_elto)
A data frame with 5233 rows and 13 variables:
Integer. Population identifier number.
Integer. Census period number (each period represents a 6-month interval, not a calendar year; periods range from 1 to 12).
Numeric. Population-level count of plantulas (seedlings,
stage "p") observed in the population at this census period.
The same value is repeated for all individuals in the same
population-period combination.
Numeric. Population-level count of adults (stage "a")
observed in the population at this census period. The same value is
repeated for all individuals in the same population-period combination.
Numeric. Mean per-individual fertility: average number of seedlings produced per adult in the population at this census period.
Integer. Unique individual plant identifier number within its population.
Character. Life history stage of the individual at the
current census: "p" (plantula/seedling), "j" (juvenile),
or "a" (adult). See Details for stage definitions.
Character. Life history stage of the individual at the
following 6-month census: "p", "j", "a", or
"m" (muerto/dead). See Details for stage definitions.
Integer. 6-month census period number when the individual was first observed (1 = first survey).
Integer. 6-month census period number when the individual was last observed alive.
Logical. TRUE if this individual was newly
recruited into the population (not present at the previous survey),
typically via sexual reproduction. All individuals at the first census
period (year == 1) are TRUE by definition as there is
no prior survey for comparison.
Logical. Whether the individual was found dead at this census period.
Integer. Total number of 6-month census periods during which the individual was observed alive (not in calendar years).
Life history stages are coded as follows:
"p" - plantula (seedling): individuals without a
lepanthiform sheet on any of the leaves
"j" - juvenile: individuals with no evidence of present
or past reproductive effort; bases of inflorescences are persistent
"a" - adult: individuals with active or inactive
inflorescences present
"m" - muerto (dead): individual was dead at the following
census (used only in next_stage)
Raymond L. Tremblay, University of Puerto Rico at Humacao, unpublished data.
Tremblay, R.L. and Hutchings, M.J. (2003). Population dynamics in orchid conservation: a review of analytical methods based on the rare species Lepanthes eltoroensis. In: Dixon, K.W. et al. (eds.) Orchid Conservation. Natural History Publications (Borneo), pp. 183–204.
Tremblay, R.L., Perez, M-E., Tyre, A.J. and Tenhumberg, B. (2021). Bayesian estimates for matrix population models of rare plants. Ecological Modelling, 440, 109526. doi:10.1016/j.ecolmodel.2021.109526
Creates a ggplot2 visualisation of the posterior mean transition
probabilities and their credible intervals for each stage, including the
probability of dying. Each panel shows the fate distribution from one
source stage.
plot_transition_CrI( cri, include_dead = TRUE, title = "Posterior transition probabilities with credible intervals" )plot_transition_CrI( cri, include_dead = TRUE, title = "Posterior transition probabilities with credible intervals" )
cri |
A data frame as returned by |
include_dead |
Logical. Whether to include the dead fate in the plot.
Defaults to |
title |
Character. Plot title. Defaults to
|
A ggplot object.
transition_CrI for computing the credible intervals.
T_mat <- matrix(c(0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7), nrow = 3, ncol = 3) F_mat <- matrix(c(0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) cri <- transition_CrI(TF, N, stage_names = c("plantula", "juvenile", "adult")) # Include dead fate (default) plot_transition_CrI(cri) # Exclude dead fate plot_transition_CrI(cri, include_dead = FALSE)T_mat <- matrix(c(0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7), nrow = 3, ncol = 3) F_mat <- matrix(c(0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) cri <- transition_CrI(TF, N, stage_names = c("plantula", "juvenile", "adult")) # Include dead fate (default) plot_transition_CrI(cri) # Exclude dead fate plot_transition_CrI(cri, include_dead = FALSE)
Creates a ggplot2 visualisation arranged as an
matrix of density plots, mirroring the structure of the population
projection matrix. Each panel shows the full marginal posterior beta
distribution for one transition probability, with the credible interval
region shaded. Columns correspond to source stages (from) and rows to
destination stages (to), including the dead fate as the bottom row.
plot_transition_density( TF, N, P = NULL, priorweight = -1, ci = 0.95, stage_names = NULL, include_dead = TRUE, title = "Posterior transition probability densities" )plot_transition_density( TF, N, P = NULL, priorweight = -1, ci = 0.95, stage_names = NULL, include_dead = TRUE, title = "Posterior transition probability densities" )
TF |
A list of two matrices, T and F, as output by
|
N |
A vector of observed stage distribution at the start of the transition period. |
P |
A matrix of priors for each column. Defaults to uniform. |
priorweight |
Total weight for each column of prior as a percentage of sample size, or 1 if negative. Defaults to -1 (uninformative). |
ci |
Credible interval width as a probability between 0 and 1. The shaded region in each panel covers this interval. Defaults to 0.95. |
stage_names |
Optional character vector of stage names in the same
order as the columns of the transition matrix. If |
include_dead |
Logical. Whether to include the dead fate as the bottom
row of the matrix plot. Defaults to |
title |
Character. Plot title. |
A ggplot object arranged as an grid (or
when include_dead = TRUE), with source stages
as columns and destination stages as rows.
transition_CrI, plot_transition_CrI.
T_mat <- matrix(c(0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7), nrow = 3, ncol = 3) F_mat <- matrix(c(0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Include dead fate as bottom row (default) plot_transition_density(TF, N, stage_names = c("plantula", "juvenile", "adult")) # Transitions only, no dead row plot_transition_density(TF, N, stage_names = c("plantula", "juvenile", "adult"), include_dead = FALSE)T_mat <- matrix(c(0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7), nrow = 3, ncol = 3) F_mat <- matrix(c(0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Include dead fate as bottom row (default) plot_transition_density(TF, N, stage_names = c("plantula", "juvenile", "adult")) # Transitions only, no dead row plot_transition_density(TF, N, stage_names = c("plantula", "juvenile", "adult"), include_dead = FALSE)
Generate n random vectors distributed according to a Dirichlet distribution. Each row of the returned matrix is a random vector that sums to 1.
rdirichlet(n, alpha)rdirichlet(n, alpha)
n |
The number of random vectors to generate |
alpha |
A vector of parameters |
The function returns a matrix with n rows and length(alpha) columns
copied from package MCMCpack to avoid a dependency. That code
was taken from Greg's Miscellaneous Functions (gregmisc). His code was based
on code posted by Ben Bolker to R-News on 15 Dec 2000.
# Generate 5 random probability vectors from a Dirichlet(1, 2, 3) distribution set.seed(42) rdirichlet(5, c(1, 2, 3))# Generate 5 random probability vectors from a Dirichlet(1, 2, 3) distribution set.seed(42) rdirichlet(5, c(1, 2, 3))
Run the interactive Shiny application for Bayesian transition priors
run_app()run_app()
No return value, called for side effects (launches a Shiny app).
if(interactive()){ raretrans::run_app() }if(interactive()){ raretrans::run_app() }
sim_transition generates a list of simulated population projection matrices from the provided parameters
and prior distributions.
sim_transitions( TF, N, P = NULL, alpha = 1e-05, beta = 1e-05, priorweight = -1, samples = 1 )sim_transitions( TF, N, P = NULL, alpha = 1e-05, beta = 1e-05, priorweight = -1, samples = 1 )
TF |
A list of two matrices, T and F, as ouput by |
N |
A vector of observed stages at start of transition. |
P |
A matrix of the priors for each column. Defaults to uniform. |
alpha |
A matrix of the prior parameter for each stage. Impossible stage combinations marked with NA_real_. |
beta |
A matrix of the prior parameter for each stage. Impossible stage combinations marked with NA_real_. |
priorweight |
total weight for each column of prior as a percentage of sample size or 1 if negative |
samples |
The number of matrices to return. |
Always returns a list.
# Build a simple 3-stage TF list T_mat <- matrix(c(0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7), nrow = 3, ncol = 3) F_mat <- matrix(c(0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Simulate 10 population projection matrices using default uninformative priors set.seed(42) mats <- sim_transitions(TF, N, samples = 10) length(mats) # 10 matrices mats[[1]] # first simulated matrix# Build a simple 3-stage TF list T_mat <- matrix(c(0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7), nrow = 3, ncol = 3) F_mat <- matrix(c(0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Simulate 10 population projection matrices using default uninformative priors set.seed(42) mats <- sim_transitions(TF, N, samples = 10) length(mats) # 10 matrices mats[[1]] # first simulated matrix
Computes the marginal posterior beta credible intervals for every entry
in the transition matrix, including the probability of dying. The marginal
posterior distribution of each transition probability follows a beta
distribution derived from the Dirichlet-multinomial model, using the
augmented fate matrix (TN) returned by fill_transitions.
transition_CrI( TF, N, P = NULL, priorweight = -1, ci = 0.95, stage_names = NULL )transition_CrI( TF, N, P = NULL, priorweight = -1, ci = 0.95, stage_names = NULL )
TF |
A list of two matrices, T and F, as output by
|
N |
A vector of observed stage distribution at the start of the transition period. |
P |
A matrix of priors for each column. Defaults to uniform. |
priorweight |
Total weight for each column of prior as a percentage of sample size, or 1 if negative. Defaults to -1 (uninformative). |
ci |
Credible interval width as a probability between 0 and 1. Defaults to 0.95 (95% credible interval). |
stage_names |
Optional character vector of stage names in the same
order as the columns of the transition matrix. If |
A data frame with one row per fate per stage (including the dead fate) and the following columns:
Character. The source stage (column of the matrix).
Character. The destination stage, including "dead".
Numeric. Posterior mean transition probability.
Numeric. Lower bound of the credible interval.
Numeric. Upper bound of the credible interval.
plot_transition_CrI for visualising the output.
T_mat <- matrix(c(0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7), nrow = 3, ncol = 3) F_mat <- matrix(c(0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Default 95% credible intervals cri <- transition_CrI(TF, N, stage_names = c("plantula", "juvenile", "adult")) cri # 90% credible intervals transition_CrI(TF, N, stage_names = c("plantula", "juvenile", "adult"), ci = 0.90)T_mat <- matrix(c(0.5, 0.3, 0.0, 0.2, 0.4, 0.1, 0.0, 0.1, 0.7), nrow = 3, ncol = 3) F_mat <- matrix(c(0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), nrow = 3, ncol = 3) TF <- list(T = T_mat, F = F_mat) N <- c(10, 5, 8) # Default 95% credible intervals cri <- transition_CrI(TF, N, stage_names = c("plantula", "juvenile", "adult")) cri # 90% credible intervals transition_CrI(TF, N, stage_names = c("plantula", "juvenile", "adult"), ci = 0.90)