R/matrixcreation.R

Defines functions summary.lefkoMat rleslie arlefko2 rlefko2 rlefko3 fleslie aflefko2 flefko2 flefko3

Documented in aflefko2 arlefko2 flefko2 flefko3 fleslie rlefko2 rlefko3 rleslie summary.lefkoMat

#' Create Function-based Historical Matrix Projection Model
#' 
#' Function \code{flefko3()} returns function-based historical MPMs
#' corresponding to the patches and occasions given, including the associated
#' component transition and fecundity matrices, data frames detailing the
#' characteristics of the ahistorical stages used and historical stage pairs
#' created, and a data frame characterizing the patch and occasion combinations
#' corresponding to these matrices.
#' 
#' @name flefko3
#' 
#' @param year A variable corresponding to the observation occasion, or a set
#' of such values, given in values associated with the year term used in linear 
#' model development. Defaults to \code{"all"}, in which case matrices will be
#' estimated for all occasions.
#' @param patch A variable designating which patches or subpopulations will have
#' matrices estimated. Defaults to \code{"all"}, but can also be set to specific
#' patch names or a vector thereof.
#' @param stageframe An object of class \code{stageframe}. These objects are
#' generated by function \code{\link{sf_create}()}, and include information on
#' the size, observation status, propagule status, reproduction status,
#' immaturity status, maturity status, stage group, size bin widths, and other
#' key characteristics of each ahistorical stage.
#' @param supplement An optional data frame of class \code{lefkoSD} that
#' provides supplemental data that should be incorporated into the MPM. Three
#' kinds of data may be integrated this way: transitions to be estimated via the
#' use of proxy transitions, transition overwrites from the literature or
#' supplemental studies, and transition multipliers for survival and fecundity.
#' This data frame should be produced using the \code{\link{supplemental}()}
#' function. Can be used in place of or in addition to an overwrite table (see 
#' \code{overwrite} below) and a reproduction matrix (see \code{repmatrix}
#' below).
#' @param repmatrix An optional reproduction matrix. This matrix is composed
#' mostly of \code{0}s, with non-zero entries acting as element identifiers and
#' multipliers for fecundity (with \code{1} equaling full fecundity). If left
#' blank, and no \code{supplement} is provided, then \code{flefko3()} will
#' assume that all stages marked as reproductive produce offspring at 1x that of
#' estimated fecundity, and that offspring production will yield the first stage
#' noted as propagule or immature. May be the dimensions of either a historical
#' or an ahistorical matrix. If the latter, then all stages will be used in
#' occasion \emph{t}-1 for each suggested ahistorical transition.
#' @param overwrite An optional data frame developed with the
#' \code{\link{overwrite}()} function describing transitions to be overwritten
#' either with given values or with other estimated transitions. Note that this
#' function supplements overwrite data provided in \code{supplement}.
#' @param data The historical vertical demographic data frame used to estimate
#' vital rates (class \code{hfvdata}), which is required to initialize times and
#' patches properly. Variable names should correspond to the naming conventions
#' in \code{\link{verticalize3}()} and \code{\link{historicalize3}()}. Not
#' required if option \code{modelsuite} is set to a \code{vrm_input} object.
#' @param modelsuite One of two kinds of lists. The first is a \code{lefkoMod}
#' object holding the vital rate models and associated metadata. Alternatively,
#' an object of class \code{vrm_input} may be provided. If given, then
#' \code{surv_model}, \code{obs_model}, \code{size_model}, \code{sizeb_model},
#' \code{sizec_model}, \code{repst_model}, \code{fec_model}, \code{jsurv_model},
#' \code{jobs_model}, \code{jsize_model}, \code{jsizeb_model},
#' \code{jsizec_model}, \code{jrepst_model}, \code{jmatst_model}, and
#' \code{paramnames} are not required. One or more of these models should
#' include size or reproductive status in occasion \emph{t}-1. Although this is
#' optional input, it is recommended, and without it all vital rate model inputs
#' (named \code{XX_model}) are required.
#' @param surv_model A linear model predicting survival probability. This can 
#' be a model of class \code{glm} or \code{glmer}, and requires a predicted
#' binomial variable under a logit link. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' the impacts of occasions \emph{t} and \emph{t}-1.
#' @param obs_model A linear model predicting sprouting or observation
#' probability. This can be a model of class \code{glm} or \code{glmer}, and
#' requires a predicted binomial variable under a logit link. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing the impacts of occasions \emph{t} and \emph{t}-1.
#' @param size_model A linear model predicting primary size. This can be a model
#' of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' the impacts of occasions \emph{t} and \emph{t}-1.
#' @param sizeb_model A linear model predicting secondary size. This can be a
#' model of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' the impacts of occasions \emph{t} and \emph{t}-1.
#' @param sizec_model A linear model predicting tertiary size. This can be a
#' model of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' the impacts of occasions \emph{t} and \emph{t}-1.
#' @param repst_model A linear model predicting reproduction probability. This 
#' can be a model of class \code{glm} or \code{glmer}, and requires a predicted
#' binomial variable under a logit link. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' the impacts of occasions \emph{t} and \emph{t}-1.
#' @param fec_model A linear model predicting fecundity. This can be a model of
#' class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl}, \code{vglm},
#' \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is provided. This
#' model must have been developed in a modeling exercise testing the impacts of
#' occasions \emph{t} and \emph{t}-1.
#' @param jsurv_model A linear model predicting juvenile survival probability.
#' This can be a model of class \code{glm} or \code{glmer}, and requires a
#' predicted binomial variable under a logit link. Ignored if \code{modelsuite}
#' is provided. This model must have been developed in a modeling exercise
#' testing the impacts of occasions \emph{t} and \emph{t}-1.
#' @param jobs_model A linear model predicting juvenile sprouting or observation
#' probability. This can be a model of class \code{glm} or \code{glmer}, and
#' requires a predicted binomial variable under a logit link. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing the impacts of occasions \emph{t} and \emph{t}-1.
#' @param jsize_model A linear model predicting juvenile primary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing the impacts of occasions \emph{t} and \emph{t}-1.
#' @param jsizeb_model A linear model predicting juvenile secondary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing the impacts of occasions \emph{t} and \emph{t}-1.
#' @param jsizec_model A linear model predicting juvenile tertiary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing the impacts of occasions \emph{t} and \emph{t}-1.
#' @param jrepst_model A linear model predicting reproduction probability of a 
#' mature individual that was immature in time \emph{t}. This can be a model
#' of class \code{glm} or \code{glmer}, and requires a predicted binomial
#' variable under a logit link. Ignored if \code{modelsuite} is provided. This
#' model must have been developed in a modeling exercise testing the impacts of
#' occasions \emph{t} and \emph{t}-1.
#' @param jmatst_model A linear model predicting maturity probability of an 
#' individual that was immature in time \emph{t}. This can be a model of class
#' \code{glm} or \code{glmer}, and requires a predicted binomial variable under
#' a logit link. Ignored if \code{modelsuite} is provided. This model must have
#' been developed in a modeling exercise testing the impacts of occasions
#' \emph{t} and \emph{t}-1.
#' @param paramnames A data frame with three columns, the first describing all
#' terms used in linear modeling, the second (must be called \code{mainparams})
#' giving the general model terms that will be used in matrix creation, and the
#' third showing the equivalent terms used in modeling (must be named
#' \code{modelparams}). Function \code{\link{create_pm}()} can be used to
#' create a skeleton \code{paramnames} object, which can then be edited. Only
#' required if \code{modelsuite} is not supplied.
#' @param inda Can be a single value to use for individual covariate \code{a}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param indb Can be a single value to use for individual covariate \code{b}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param indc Can be a single value to use for individual covariate \code{c}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param surv_dev A numeric value to be added to the y-intercept in the linear
#' model for survival probability. Defaults to \code{0}.
#' @param obs_dev A numeric value to be added to the y-intercept in the linear
#' model for observation probability. Defaults to \code{0}.
#' @param size_dev A numeric value to be added to the y-intercept in the linear
#' model for primary size. Defaults to \code{0}.
#' @param sizeb_dev A numeric value to be added to the y-intercept in the linear
#' model for secondary size. Defaults to \code{0}.
#' @param sizec_dev A numeric value to be added to the y-intercept in the linear
#' model for tertiary size. Defaults to \code{0}.
#' @param repst_dev A numeric value to be added to the y-intercept in the linear
#' model for probability of reproduction. Defaults to \code{0}.
#' @param fec_dev A numeric value to be added to the y-intercept in the linear
#' model for fecundity. Defaults to \code{0}.
#' @param jsurv_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile survival probability. Defaults to \code{0}.
#' @param jobs_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile observation probability. Defaults to \code{0}.
#' @param jsize_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile primary size. Defaults to \code{0}.
#' @param jsizeb_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile secondary size. Defaults to \code{0}.
#' @param jsizec_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile tertiary size. Defaults to \code{0}.
#' @param jrepst_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile reproduction probability. Defaults to \code{0}.
#' @param jmatst_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile maturity probability. Defaults to \code{0}.
#' @param density A numeric value indicating density value to use to propagate
#' matrices. Only needed if density is an explanatory term used in one or more
#' vital rate models. Defaults to \code{NA}.
#' @param fecmod A scalar multiplier of fecundity. Defaults to \code{1.0}.
#' @param random.inda A logical value denoting whether to treat individual
#' covariate \code{a} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param random.indb A logical value denoting whether to treat individual
#' covariate \code{b} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param random.indc A logical value denoting whether to treat individual
#' covariate \code{c} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param negfec A logical value denoting whether fecundity values estimated to
#' be negative should be reset to \code{0}. Defaults to \code{FALSE}.
#' @param format A string indicating whether to estimate matrices in
#' \code{ehrlen} format or \code{deVries} format. The latter adds one extra
#' prior stage to account for the prior state of newborns. Defaults to
#' \code{ehrlen} format.
#' @param ipm_method A string indicating what method to use to estimate size
#' transition probabilities, if size is treated as continuous. Options include:
#' \code{"midpoint"}, which utilizes the midpoint method; and \code{"CDF"},
#' which uses the cumulative distribution function. Defaults to \code{"CDF"}.
#' @param reduce A logical value denoting whether to remove historical stages
#' associated solely with \code{0} transitions. These are only removed in cases
#' where the associated row and column sums in ALL matrices estimated equal 0. 
#' Defaults to \code{FALSE}.
#' @param simple A logical value indicating whether to produce \code{A},
#' \code{U}, and \code{F} matrices, or only the latter two. Defaults to
#' \code{FALSE}, in which case all three are output.
#' @param err_check A logical value indicating whether to append extra
#' information used in matrix calculation within the output list. Defaults to
#' \code{FALSE}.
#' @param exp_tol A numeric value used to indicate a maximum value to set
#' exponents to in the core kernel to prevent numerical overflow. Defaults to
#' \code{700}.
#' @param theta_tol A numeric value used to indicate a maximum value to theta as
#' used in the negative binomial probability density kernel. Defaults to
#' \code{100000000}, but can be reset to other values during error checking.
#' @param sparse_output A logical value indicating whether to output matrices
#' in sparse format. Defaults to \code{FALSE}, in which case all matrices are
#' output in standard matrix format.
#'
#' @return If all inputs are properly formatted, then this function will return
#' an object of class \code{lefkoMat}, which is a list that holds the matrix
#' projection model and all of its metadata. The structure has the following
#' elements:
#' 
#' \item{A}{A list of full projection matrices in order of sorted patches and
#' occasion times. All matrices output in R's \code{matrix} class, or in
#' the \code{dgCMatrix} class from the \code{Matrix} package if sparse.}
#' \item{U}{A list of survival transition matrices sorted as in \code{A}. All 
#' matrices output in R's \code{matrix} class, or in the \code{dgCMatrix} class
#' from the \code{Matrix} package if sparse.}
#' \item{F}{A list of fecundity matrices sorted as in \code{A}. All matrices 
#' output in R's \code{matrix} class, or in the \code{dgCMatrix} class from the
#' \code{Matrix} package if sparse.}
#' \item{hstages}{A data frame matrix showing the pairing of ahistorical stages
#' used to create historical stage pairs.}
#' \item{agestages}{A data frame showing age-stage pairs. In this function, it
#' is set to \code{NA}. Only used in output to function \code{aflefko2}().}
#' \item{ahstages}{A data frame detailing the characteristics of associated
#' ahistorical stages, in the form of a modified stageframe that includes
#' status as an entry stage through reproduction.}
#' \item{labels}{A data frame giving the population, patch, and year of each
#' matrix in order. In \code{flefko3()}, only one population may be analyzed at
#' once.}
#' \item{dataqc}{A vector showing the numbers of individuals and rows in the
#' vertical dataset used as input.}
#' \item{matrixqc}{A short vector describing the number of non-zero elements in
#' \code{U} and \code{F} matrices, and the number of annual matrices.}
#' \item{modelqc}{This is the \code{qc} portion of the \code{modelsuite} input.}
#' \item{prob_out}{An optional element only added if \code{err_check = TRUE}.
#' This is a list of vital rate probability matrices, with 7 columns in the
#' order of survival, observation probability, reproduction probability, primary
#' size transition probability, secondary size transition probability, tertiary
#' size transition probability, and probability of juvenile transition to
#' maturity.}
#' \item{allstages}{An optional element only added if \code{err_check = TRUE}.
#' This is a data frame giving the values used to determine each matrix element
#' capable of being estimated.}
#' 
#' @section Notes:
#' Unlike \code{\link{rlefko2}()}, \code{\link{rlefko3}()},
#' \code{\link{arlefko2}()}, and \code{\link{rleslie}()}, this function does not
#' currently distinguish populations. Users wishing to use the same vital rate
#' models across populations should label them as patches (though we do not
#' advise this approach, as populations should typically be treated as
#' statistically independent).
#' 
#' The default behavior of this function is to estimate fecundity with regards
#' to transitions specified via associated fecundity multipliers in either
#' \code{supplement} or \code{repmatrix}. If both of these fields are left
#' empty, then fecundity will be estimated at full for all transitions leading
#' from reproductive stages to immature and propagule stages. However, if a
#' \code{supplement} is provided and a \code{repmatrix} is not, or if
#' \code{repmatrix} is set to \code{0}, then only fecundity transitions noted in
#' the \code{supplement} will be set to non-zero values. To use the default
#' behavior of setting all reproductive stages to reproduce at full fecundity
#' into immature and propagule stages, but also incorporate given or proxy
#' survival transitions, input those given and proxy transitions through the
#' \code{overwrite} option.
#' 
#' If used, the reproduction matrix (field \code{repmatrix}) may be supplied as
#' either historical or ahistorical. If provided as ahistorical, then
#' \code{flefko3()} will assume that all historical transitions involving stages
#' noted for occasions \emph{t} and \emph{t}+1 should be set to the respective
#' fecundity multipliers noted.
#' 
#' Users may at times wish to estimate MPMs using a dataset incorporating
#' multiple patches or subpopulations, but without discriminating between those
#' patches or subpopulations. Should the aim of analysis be a general MPM that
#' does not distinguish these patches or subpopulations, the
#' \code{modelsearch()} run should not include patch terms.
#'
#' Input options including multiple variable names must be entered in the order
#' of variables in occasion \emph{t}+1, \emph{t}, and \emph{t}-1. Rearranging
#' the order will lead to erroneous calculations, and will may lead to fatal
#' errors.
#' 
#' The \code{ipm_method} function gives the option of using two different means
#' of estimating the probability of size transition. The midpoint method
#' (\code{"midpoint"}) refers to the method in which the probability is
#' estimated by first estimating the probability associated with transition from
#' the exact size at the midpoint of the size class using the corresponding
#' probability density function, and then multiplying that value by the bin
#' width of the size class. Doak et al. 2021 (Ecological Monographs) noted that
#' this method can produce biased results, with total size transitions
#' associated with a specific size not totaling to 1.0 and even specific size
#' transition probabilities capable of being estimated at values greater than
#' 1.0. The alternative and default method, \code{"CDF"}, uses the corresponding
#' cumulative density function to estimate the probability of size transition as
#' the cumulative probability of size transition at the greater limit of the
#' size class minus the cumulative probability of size transition at the lower
#' limit of the size class. This latter method avoids this bias. Note, however,
#' that both methods are exact and unbiased for negative binomial and Poisson
#' distributions.
#' 
#' Under the Gaussian and gamma size distributions, the number of estimated
#' parameters may differ between the two \code{ipm_method} settings. Because
#' the midpoint method has a tendency to incorporate upward bias in the
#' estimation of size transition probabilities, it is more likely to yield non-
#' zero values when the true probability is extremely close to 0. This will
#' result in the \code{summary.lefkoMat} function yielding higher numbers of
#' estimated parameters than the \code{ipm_method = "CDF"} yields in some cases.
#' 
#' Using the \code{err_check} option will produce a matrix of 7 columns, each
#' characterizing a different vital rate. The product of each row yields an
#' element in the associated \code{U} matrix. The number and order of elements
#' in each column of this matrix matches the associated matrix in column vector
#' format. Use of this option is generally for the purposes of debugging code.
#'`
#' Individual covariates are treated as categorical only if they are set as
#' random terms. Fixed categorical individual covariates are currently not
#' allowed. However, such terms may be supplied if the \code{modelsuite} option
#' is set to a \code{vrm_input} object. In that case, the user should also set
#' the logical random switch for the individual covariate to be used to 
#' \code{TRUE} (e.g., \code{random.inda = TRUE}).
#' 
#' @seealso \code{\link{mpm_create}()}
#' @seealso \code{\link{flefko2}()}
#' @seealso \code{\link{aflefko2}()}
#' @seealso \code{\link{arlefko2}()}
#' @seealso \code{\link{fleslie}()}
#' @seealso \code{\link{rlefko3}()}
#' @seealso \code{\link{rlefko2}()}
#' @seealso \code{\link{rleslie}()}
#' 
#' @examples
#' \donttest{
#' # Lathyrus example
#' data(lathyrus)
#' 
#' sizevector <- c(0, 4.6, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8,
#'   9)
#' stagevector <- c("Sd", "Sdl", "Dorm", "Sz1nr", "Sz2nr", "Sz3nr", "Sz4nr",
#'   "Sz5nr", "Sz6nr", "Sz7nr", "Sz8nr", "Sz9nr", "Sz1r", "Sz2r", "Sz3r", 
#'   "Sz4r", "Sz5r", "Sz6r", "Sz7r", "Sz8r", "Sz9r")
#' repvector <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' obsvector <- c(0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' matvector <- c(0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' immvector <- c(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
#'   0)
#' indataset <- c(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' binvec <- c(0, 4.6, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 
#'   0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5)
#' 
#' lathframeln <- sf_create(sizes = sizevector, stagenames = stagevector, 
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector, 
#'   immstatus = immvector, indataset = indataset, binhalfwidth = binvec, 
#'   propstatus = propvector)
#' 
#' lathvertln <- verticalize3(lathyrus, noyears = 4, firstyear = 1988,
#'   patchidcol = "SUBPLOT", individcol = "GENET", blocksize = 9, 
#'   juvcol = "Seedling1988", sizeacol = "lnVol88", repstracol = "Intactseed88",
#'   fecacol = "Intactseed88", deadacol = "Dead1988", 
#'   nonobsacol = "Dormant1988", stageassign = lathframeln, stagesize = "sizea",
#'   censorcol = "Missing1988", censorkeep = NA, NAas0 = TRUE, censor = TRUE)
#' 
#' lathvertln$feca2 <- round(lathvertln$feca2)
#' lathvertln$feca1 <- round(lathvertln$feca1)
#' lathvertln$feca3 <- round(lathvertln$feca3)
#' 
#' lathmodelsln3 <- modelsearch(lathvertln, historical = TRUE, 
#'   approach = "mixed", suite = "main", 
#'   vitalrates = c("surv", "obs", "size", "repst", "fec"), juvestimate = "Sdl",
#'   bestfit = "AICc&k", sizedist = "gaussian", fecdist = "poisson", 
#'   indiv = "individ", patch = "patchid", year = "year2", year.as.random = TRUE,
#'   patch.as.random = TRUE, show.model.tables = TRUE, quiet = "partial")
#' 
#' lathsupp3 <- supplemental(stage3 = c("Sd", "Sd", "Sdl", "Sdl", "mat", "Sd", "Sdl"), 
#'   stage2 = c("Sd", "Sd", "Sd", "Sd", "Sdl", "rep", "rep"),
#'   stage1 = c("Sd", "rep", "Sd", "rep", "Sd", "mat", "mat"),
#'   eststage3 = c(NA, NA, NA, NA, "mat", NA, NA),
#'   eststage2 = c(NA, NA, NA, NA, "Sdl", NA, NA),
#'   eststage1 = c(NA, NA, NA, NA, "Sdl", NA, NA),
#'   givenrate = c(0.345, 0.345, 0.054, 0.054, NA, NA, NA),
#'   multiplier = c(NA, NA, NA, NA, NA, 0.345, 0.054),
#'   type = c(1, 1, 1, 1, 1, 3, 3), type_t12 = c(1, 2, 1, 2, 1, 1, 1),
#'   stageframe = lathframeln, historical = TRUE)
#' 
#' lathmat3ln <- flefko3(year = "all", patch = "all", stageframe = lathframeln, 
#'   modelsuite = lathmodelsln3, data = lathvertln, supplement = lathsupp3, 
#'   reduce = FALSE)
#' 
#' #Cypripedium example using three size metrics for classification
#' data(cypdata)
#' sizevector_f <- c(0, 0, 0, 0, 0, 0, seq(1, 12, by = 1), seq(0, 9, by = 1),
#'   seq(0, 8, by = 1), seq(0, 7, by = 1), seq(0, 6, by = 1), seq(0, 5, by = 1),
#'   seq(0, 4, by = 1), seq(0, 3, by = 1), 0, 1, 2, 0, 1, 0, 
#'   0, 0, 1, 0)
#' sizebvector_f <- c(0, 0, 0, 0, 0, 0, rep(0, 12), rep(1, 10), rep(2, 9),
#'   rep(3, 8), rep(4, 7), rep(5, 6), rep(6, 5), rep(7, 4), rep(8, 3), 9, 9, 10, 
#'   0, 1, 1, 2)
#' sizecvector_f <- c(0, 0, 0, 0, 0, 0, rep(0, 12), rep(0, 10), rep(0, 9),
#'   rep(0, 8), rep(0, 7), rep(0, 6), rep(0, 5), rep(0, 4), 0, 0, 0, 0, 0, 0, 
#'   1, 1, 1, 1)
#' stagevector_f <- c("DS", "P1", "P2", "P3", "Sdl", "Dorm", "V1 I0 D0",
#'   "V2 I0 D0", "V3 I0 D0", "V4 I0 D0", "V5 I0 D0", "V6 I0 D0", "V7 I0 D0",
#'   "V8 I0 D0", "V9 I0 D0", "V10 I0 D0", "V11 I0 D0", "V12 I0 D0", "V0 I1 D0",
#'   "V1 I1 D0", "V2 I1 D0", "V3 I1 D0", "V4 I1 D0", "V5 I1 D0", "V6 I1 D0",
#'   "V7 I1 D0", "V8 I1 D0", "V9 I1 D0", "V0 I2 D0", "V1 I2 D0", "V2 I2 D0",
#'   "V3 I2 D0", "V4 I2 D0", "V5 I2 D0", "V6 I2 D0", "V7 I2 D0", "V8 I2 D0",
#'   "V0 I3 D0", "V1 I3 D0", "V2 I3 D0", "V3 I3 D0", "V4 I3 D0", "V5 I3 D0",
#'   "V6 I3 D0", "V7 I3 D0", "V0 I4 D0", "V1 I4 D0", "V2 I4 D0", "V3 I4 D0",
#'   "V4 I4 D0", "V5 I4 D0", "V6 I4 D0", "V0 I5 D0", "V1 I5 D0", "V2 I5 D0",
#'   "V3 I5 D0", "V4 I5 D0", "V5 I5 D0", "V0 I6 D0", "V1 I6 D0", "V2 I6 D0",
#'   "V3 I6 D0", "V4 I6 D0", "V0 I7 D0", "V1 I7 D0", "V2 I7 D0", "V3 I7 D0",
#'   "V0 I8 D0", "V1 I8 D0", "V2 I8 D0", "V0 I9 D0", "V1 I9 D0", "V0 I10 D0",
#'   "V0 I0 D1", "V0 I1 D1", "V1 I1 D1", "V0 I2 D1")
#' repvector_f <- c(0, 0, 0, 0, 0, rep(0, 13), rep(1, 59))
#' obsvector_f <- c(0, 0, 0, 0, 0, 0, rep(1, 71))
#' matvector_f <- c(0, 0, 0, 0, 0, rep(1, 72))
#' immvector_f <- c(0, 1, 1, 1, 1, rep(0, 72))
#' propvector_f <- c(1, rep(0, 76))
#' indataset_f <- c(0, 0, 0, 0, 0, rep(1, 72))
#' binvec_f <- c(0, 0, 0, 0, 0, rep(0.5, 72))
#' binbvec_f <- c(0, 0, 0, 0, 0, rep(0.5, 72))
#' bincvec_f <- c(0, 0, 0, 0, 0, rep(0.5, 72))
#' 
#' vertframe_f <- sf_create(sizes = sizevector_f, sizesb = sizebvector_f,
#'   sizesc = sizecvector_f, stagenames = stagevector_f, repstatus = repvector_f,
#'   obsstatus = obsvector_f, propstatus = propvector_f, immstatus = immvector_f,
#'   matstatus = matvector_f, indataset = indataset_f, binhalfwidth = binvec_f,
#'   binhalfwidthb = binbvec_f, binhalfwidthc = bincvec_f)
#' 
#' vert_data_f <- verticalize3(cypdata, noyears = 6, firstyear = 2004,
#'   individcol = "plantid", blocksize = 4, sizeacol = "Veg.04",
#'   sizebcol = "Inf.04", sizeccol = "Inf2.04", repstracol = "Inf.04",
#'   repstrbcol = "Inf2.04", fecacol = "Pod.04", censorcol = "censor",
#'   censorkeep = 1, censorRepeat = FALSE, stageassign = vertframe_f,
#'   stagesize = "sizeabc", NAas0 = TRUE, censor = FALSE)
#' 
#' vertmodels3f <- modelsearch(vert_data_f, historical = TRUE, suite = "main",
#'   sizeb = c("sizeb3", "sizeb2", "sizeb1"), sizec = c("sizec3", "sizec2", "sizec1"),
#'   approach = "glm", vitalrates = c("surv", "obs", "size", "repst", "fec"),
#'   sizedist = "negbin", sizebdist = "poisson", sizecdist = "poisson",
#'   fecdist = "poisson", patch.as.random = TRUE, year.as.random = TRUE,
#'   quiet = "partial")
#' 
#' vertsupp3f <- supplemental(stage3 = c("DS", "P1", "DS", "P1", "P2", "P2", "P3",
#'     "Sdl", "Sdl", "Sdl", "Dorm", "V1 I0 D0", "V2 I0 D0", "V3 I0 D0", "Dorm",
#'     "V1 I0 D0", "V2 I0 D0", "V3 I0 D0", "mat", "mat", "mat", "mat", "DS", "P1"),
#'   stage2 = c("DS", "DS", "DS", "DS", "P1", "P1", "P2", "P3", "Sdl", "Sdl", "Sdl",
#'     "Sdl", "Sdl", "Sdl", "Sdl", "Sdl", "Sdl", "Sdl", "Dorm", "V1 I0 D0",
#'     "V2 I0 D0", "V3 I0 D0", "rep", "rep"),
#'   stage1 = c("DS", "DS", "rep", "rep", "DS", "rep", "P1", "P2", "P3", "Sdl",
#'     "Sdl", "Sdl", "Sdl", "Sdl", "P3", "P3", "P3", "P3", "Sdl", "Sdl", "Sdl",
#'     "Sdl", "mat", "mat"),
#'   eststage3 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Dorm", "V1 I0 D0",
#'     "V2 I0 D0", "V3 I0 D0", "Dorm", "V1 I0 D0", "V2 I0 D0", "V3 I0 D0", "mat",
#'     "mat", "mat", "mat", NA, NA), 
#'   eststage2 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "V1 I0 D0", "V1 I0 D0",
#'     "V1 I0 D0", "V1 I0 D0", "V1 I0 D0", "V1 I0 D0", "V1 I0 D0", "V1 I0 D0",
#'     "Dorm", "V1 I0 D0", "V2 I0 D0", "V3 I0 D0", NA, NA),
#'   eststage1 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "V1 I0 D0", "V1 I0 D0",
#'     "V1 I0 D0", "V1 I0 D0", "V1 I0 D0", "V1 I0 D0", "V1 I0 D0", "V1 I0 D0",
#'     "V1 I0 D0", "V1 I0 D0", "V1 I0 D0", "V1 I0 D0", NA, NA),
#'   givenrate = c(0.10, 0.20, 0.10, 0.20, 0.20, 0.20, 0.20, 0.25, 0.40, 0.40, NA,
#'     NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
#'   multiplier = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
#'     NA, NA, NA, NA, NA, NA, NA, 0.5 * 5000, 0.5 * 5000),
#'   type =c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#'     3, 3),
#'   type_t12 = c(1, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#'     1, 1, 1),
#'   stageframe = vertframe_f, historical = TRUE)
#' 
#' vert_mats_f3 <- flefko3(stageframe = vertframe_f, supplement = vertsupp3f, 
#'   data = vert_data_f, modelsuite = vertmodels3f)
#' }
#' 
#' @export
flefko3 <- function(year = "all", patch = "all", stageframe, supplement = NULL,
  repmatrix = NULL, overwrite = NULL, data = NULL, modelsuite = NULL,
  surv_model = NULL, obs_model = NULL, size_model = NULL, sizeb_model = NULL,
  sizec_model = NULL, repst_model = NULL, fec_model = NULL, jsurv_model = NULL,
  jobs_model = NULL, jsize_model = NULL, jsizeb_model = NULL,
  jsizec_model = NULL, jrepst_model = NULL, jmatst_model = NULL,
  paramnames = NULL, inda = NULL, indb = NULL, indc = NULL, surv_dev = 0,
  obs_dev = 0, size_dev = 0, sizeb_dev = 0, sizec_dev = 0, repst_dev = 0,
  fec_dev = 0, jsurv_dev = 0, jobs_dev = 0, jsize_dev = 0, jsizeb_dev = 0,
  jsizec_dev = 0, jrepst_dev = 0, jmatst_dev = 0, density = NA, fecmod = 1.0,
  random.inda = FALSE, random.indb = FALSE, random.indc = FALSE,
  negfec = FALSE, format = "ehrlen", ipm_method = "CDF", reduce = FALSE,
  simple = FALSE, err_check = FALSE, exp_tol = 700, theta_tol = 100000000,
  sparse_output = FALSE) {
  
  format_dev <- FALSE
  cdf <- TRUE
  
  if (grepl("dev", tolower(format))) {
    format_dev <- TRUE
  }
  
  ipm_method <- tolower(ipm_method)
  if (grepl("mi", ipm_method)) {
    cdf <- FALSE
  }
  
  devterms <- c(surv_dev, obs_dev, size_dev, sizeb_dev, sizec_dev, repst_dev,
    fec_dev, jsurv_dev, jobs_dev, jsize_dev, jsizeb_dev, jsizec_dev, jrepst_dev,
    jmatst_dev)
  
  if (is.null(modelsuite)) {
    if (!is.null(surv_model)) {
      modelsuite <- list(surv_model = surv_model, obs_model = obs_model,
        size_model = size_model, sizeb_model = sizeb_model,
        sizec_model = sizec_model, repst_model = repst_model,
        fec_model = fec_model, jsurv_model = jsurv_model,
        jobs_model = jobs_model, jsize_model = jsize_model,
        jsizeb_model = jsizeb_model, jsizec_model = jsizec_model,
        jrepst_model = jrepst_model, jmatst_model = jmatst_model)
      if (!is.null(paramnames)) modelsuite$paramnames <- paramnames
    }
  }
  
  output <- mpm_create(historical = TRUE, stage = TRUE, age = FALSE,
    devries = format_dev, reduce = reduce, data = data, year = year,
    patch = patch, stageframe = stageframe, supplement = supplement,
    overwrite = overwrite, repmatrix = repmatrix, modelsuite = modelsuite,
    paramnames = paramnames, inda = inda, indb = indb, indc = indc,
    dev_terms = devterms, density = density, fecmod = fecmod, CDF = cdf,
    random_inda = random.inda, random_indb = random.indb,
    random_indc = random.indc, negfec = negfec, exp_tol = exp_tol,
    theta_tol = theta_tol, simple = simple, err_check = err_check,
    sparse_output = sparse_output)  
  
  return(output)
}

#' Create Function-based Ahistorical Matrix Projection Model
#'
#' Function \code{flefko2()} returns ahistorical MPMs corresponding to the
#' patches and occasions given, including the associated component transition
#' and fecundity matrices, a data frame detailing the characteristics of the
#' ahistorical stages used, and a data frame characterizing the patch and
#' occasion combinations corresponding to these matrices.
#' 
#' @name flefko2
#' 
#' @param year A variable corresponding to the observation occasion, or a set
#' of such values, given in values associated with the year term used in linear 
#' model development. Defaults to \code{"all"}, in which case matrices will be
#' estimated for all occasions.
#' @param patch A variable designating which patches or subpopulations will have
#' matrices estimated. Defaults to \code{"all"}, but can also be set to specific
#' patch names or a vector thereof.
#' @param stageframe An object of class \code{stageframe}. These objects are
#' generated by function \code{\link{sf_create}()}, and include information on
#' the size, observation status, propagule status, reproduction status,
#' immaturity status, maturity status, stage group, size bin widths, and other
#' key characteristics of each ahistorical stage.
#' @param supplement An optional data frame of class \code{lefkoSD} that
#' provides supplemental data that should be incorporated into the MPM. Three
#' kinds of data may be integrated this way: transitions to be estimated via the
#' use of proxy transitions, transition overwrites from the literature or
#' supplemental studies, and transition multipliers for survival and fecundity.
#' This data frame should be produced using the \code{\link{supplemental}()}
#' function. Can be used in place of or in addition to an overwrite table (see 
#' \code{overwrite} below) and a reproduction matrix (see \code{repmatrix}
#' below).
#' @param repmatrix An optional reproduction matrix. This matrix is composed
#' mostly of \code{0}s, with non-zero entries acting as element identifiers and
#' multipliers for fecundity (with \code{1} equaling full fecundity). If left
#' blank, and no \code{supplement} is provided, then \code{flefko2()} will
#' assume that all stages marked as reproductive produce offspring at 1x that of
#' estimated fecundity, and that offspring production will yield the first stage
#' noted as propagule or immature. Must be the dimensions of an ahistorical
#' matrix.
#' @param overwrite An optional data frame developed with the
#' \code{\link{overwrite}()} function describing transitions to be overwritten
#' either with given values or with other estimated transitions. Note that this
#' function supplements overwrite data provided in \code{supplement}.
#' @param data  The historical vertical demographic data frame used to estimate
#' vital rates (class \code{hfvdata}), which is required to initialize times and
#' patches properly. Variable names should correspond to the naming conventions
#' in \code{\link{verticalize3}()} and \code{\link{historicalize3}()}. Not
#' required if option \code{modelsuite} is set to a \code{vrm_input} object.
#' @param modelsuite One of two kinds of lists. The first is a \code{lefkoMod}
#' object holding the vital rate models and associated metadata. Alternatively,
#' an object of class \code{vrm_input} may be provided. If given, then
#' \code{surv_model}, \code{obs_model}, \code{size_model}, \code{sizeb_model},
#' \code{sizec_model}, \code{repst_model}, \code{fec_model}, \code{jsurv_model},
#' \code{jobs_model}, \code{jsize_model}, \code{jsizeb_model},
#' \code{jsizec_model}, \code{jrepst_model}, \code{jmatst_model}, and
#' \code{paramnames} are not required. No models should include size or
#' reproductive status in occasion \emph{t}-1. Although this is optional input,
#' it is recommended, and without it all vital rate model inputs (named
#' \code{XX_model}) are required.
#' @param surv_model A linear model predicting survival probability. This can 
#' be a model of class \code{glm} or \code{glmer}, and requires a predicted
#' binomial variable under a logit link. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param obs_model A linear model predicting sprouting or observation
#' probability. This can be a model of class \code{glm} or \code{glmer}, and
#' requires a predicted binomial variable under a logit link. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param size_model A linear model predicting primary size. This can be a model
#' of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param sizeb_model A linear model predicting secondary size. This can be a
#' model of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param sizec_model A linear model predicting tertiary size. This can be a
#' model of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param repst_model A linear model predicting reproduction probability. This 
#' can be a model of class \code{glm} or \code{glmer}, and requires a predicted
#' binomial variable under a logit link. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param fec_model A linear model predicting fecundity. This can be a model of
#' class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl}, \code{vglm},
#' \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is provided. This
#' model must have been developed in a modeling exercise testing only the
#' impacts of occasion \emph{t}.
#' @param jsurv_model A linear model predicting juvenile survival probability.
#' This can be a model of class \code{glm} or \code{glmer}, and requires a
#' predicted binomial variable under a logit link. Ignored if \code{modelsuite}
#' is provided. This model must have been developed in a modeling exercise
#' testing only the impacts of occasion \emph{t}.
#' @param jobs_model A linear model predicting juvenile sprouting or observation
#' probability. This can be a model of class \code{glm} or \code{glmer}, and
#' requires a predicted binomial variable under a logit link. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param jsize_model A linear model predicting juvenile primary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param jsizeb_model A linear model predicting juvenile secondary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param jsizec_model A linear model predicting juvenile tertiary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param jrepst_model A linear model predicting reproduction probability of a 
#' mature individual that was immature in time \emph{t}. This can be a model
#' of class \code{glm} or \code{glmer}, and requires a predicted binomial
#' variable under a logit link. Ignored if \code{modelsuite} is provided. This
#' model must have been developed in a modeling exercise testing only the
#' impacts of occasion \emph{t}.
#' @param jmatst_model A linear model predicting maturity probability of an 
#' individual that was immature in time \emph{t}. This can be a model of class
#' \code{glm} or \code{glmer}, and requires a predicted binomial variable under
#' a logit link. Ignored if \code{modelsuite} is provided. This model must have
#' been developed in a modeling exercise testing only the impacts of occasion
#' \emph{t}.
#' @param paramnames A data frame with three columns, the first describing all
#' terms used in linear modeling, the second (must be called \code{mainparams})
#' giving the general model terms that will be used in matrix creation, and the
#' third showing the equivalent terms used in modeling (must be named
#' \code{modelparams}). Function \code{\link{create_pm}()} can be used to
#' create a skeleton \code{paramnames} object, which can then be edited. Only
#' required if \code{modelsuite} is not supplied.
#' @param inda Can be a single value to use for individual covariate \code{a}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param indb Can be a single value to use for individual covariate \code{b}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param indc Can be a single value to use for individual covariate \code{c}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param surv_dev A numeric value to be added to the y-intercept in the linear
#' model for survival probability. Defaults to \code{0}.
#' @param obs_dev A numeric value to be added to the y-intercept in the linear
#' model for observation probability. Defaults to \code{0}.
#' @param size_dev A numeric value to be added to the y-intercept in the linear
#' model for primary size. Defaults to \code{0}.
#' @param sizeb_dev A numeric value to be added to the y-intercept in the linear
#' model for secondary size. Defaults to \code{0}.
#' @param sizec_dev A numeric value to be added to the y-intercept in the linear
#' model for tertiary size. Defaults to \code{0}.
#' @param repst_dev A numeric value to be added to the y-intercept in the linear
#' model for probability of reproduction. Defaults to \code{0}.
#' @param fec_dev A numeric value to be added to the y-intercept in the linear
#' model for fecundity. Defaults to \code{0}.
#' @param jsurv_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile survival probability. Defaults to \code{0}.
#' @param jobs_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile observation probability. Defaults to \code{0}.
#' @param jsize_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile primary size. Defaults to \code{0}.
#' @param jsizeb_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile secondary size. Defaults to \code{0}.
#' @param jsizec_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile tertiary size. Defaults to \code{0}.
#' @param jrepst_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile reproduction probability. Defaults to \code{0}.
#' @param jmatst_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile maturity probability. Defaults to \code{0}.
#' @param density A numeric value indicating density value to use to propagate
#' matrices. Only needed if density is an explanatory term used in one or more
#' vital rate models. Defaults to \code{NA}.
#' @param fecmod A scalar multiplier of fecundity. Defaults to \code{1.0}.
#' @param random.inda A logical value denoting whether to treat individual
#' covariate \code{a} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param random.indb A logical value denoting whether to treat individual
#' covariate \code{b} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param random.indc A logical value denoting whether to treat individual
#' covariate \code{c} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param negfec A logical value denoting whether fecundity values estimated to
#' be negative should be reset to \code{0}. Defaults to \code{FALSE}.
#' @param ipm_method A string indicating what method to use to estimate size
#' transition probabilities, if size is treated as continuous. Options include:
#' \code{"midpoint"}, which utilizes the midpoint method; and \code{"CDF"},
#' which uses the cumulative distribution function. Defaults to \code{"CDF"}.
#' @param reduce A logical value denoting whether to remove ahistorical stages
#' associated solely with \code{0} transitions. These are only removed in cases
#' where the associated row and column sums in ALL matrices estimated equal 0. 
#' Defaults to \code{FALSE}.
#' @param simple A logical value indicating whether to produce \code{A},
#' \code{U}, and \code{F} matrices, or only the latter two. Defaults to
#' \code{FALSE}, in which case all three are output.
#' @param err_check A logical value indicating whether to append extra
#' information used in matrix calculation within the output list. Defaults to
#' \code{FALSE}.
#' @param exp_tol A numeric value used to indicate a maximum value to set
#' exponents to in the core kernel to prevent numerical overflow. Defaults to
#' \code{700}.
#' @param theta_tol A numeric value used to indicate a maximum value to theta as
#' used in the negative binomial probability density kernel. Defaults to
#' \code{100000000}, but can be reset to other values during error checking.
#' @param sparse_output A logical value indicating whether to output matrices
#' in sparse format. Defaults to \code{FALSE}, in which case all matrices are
#' output in standard matrix format.
#'
#' @return If all inputs are properly formatted, then this function will return
#' an object of class \code{lefkoMat}, which is a list that holds the matrix
#' projection model and all of its metadata. The structure has the following
#' elements:
#'
#' \item{A}{A list of full projection matrices in order of sorted patches and
#' occasion times. All matrices output in R's \code{matrix} class, or in
#' the \code{dgCMatrix} class from the \code{Matrix} package if sparse.}
#' \item{U}{A list of survival transition matrices sorted as in \code{A}. All 
#' matrices output in R's \code{matrix} class, or in the \code{dgCMatrix} class
#' from the \code{Matrix} package if sparse.}
#' \item{F}{A list of fecundity matrices sorted as in \code{A}. All matrices 
#' output in R's \code{matrix} class, or in the \code{dgCMatrix} class from the
#' \code{Matrix} package if sparse.}
#' \item{hstages}{A data frame matrix showing the pairing of ahistorical stages
#' used to create historical stage pairs. Set to \code{NA} for ahistorical
#' matrices.}
#' \item{agestages}{A data frame showing age-stage pairs. In this function, it
#' is set to \code{NA}. Only used in output to function \code{aflefko2}().}
#' \item{ahstages}{A data frame detailing the characteristics of associated
#' ahistorical stages, in the form of a modified stageframe that includes
#' status as an entry stage through reproduction.}
#' \item{labels}{A data frame giving the population, patch, and year of each
#' matrix in order. In \code{flefko2()}, only one population may be analyzed at
#' once.}
#' \item{dataqc}{A vector showing the numbers of individuals and rows in the
#' vertical dataset used as input.}
#' \item{matrixqc}{A short vector describing the number of non-zero elements in
#' \code{U} and \code{F} matrices, and the number of annual matrices.}
#' \item{modelqc}{This is the \code{qc} portion of the \code{modelsuite} input.}
#' \item{prob_out}{An optional element only added if \code{err_check = TRUE}.
#' This is a list of vital rate probability matrices, with 7 columns in the
#' order of survival, observation probability, reproduction probability, primary
#' size transition probability, secondary size transition probability, tertiary
#' size transition probability, and probability of juvenile transition to
#' maturity.}
#' \item{allstages}{An optional element only added if \code{err_check = TRUE}.
#' This is a data frame giving the values used to determine each matrix element
#' capable of being estimated.}
#' 
#' @section Notes:
#' Unlike \code{\link{rlefko2}()}, \code{\link{rlefko3}()},
#' \code{\link{arlefko2}()}, and \code{\link{rleslie}()}, this function does not
#' currently distinguish populations. Users wishing to use the same vital rate
#' models across populations should label them as patches (though we do not
#' advise this approach, as populations should typically be treated as
#' statistically independent).
#' 
#' This function will yield incorrect estimates if the models utilized
#' incorporate state in occasion \emph{t}-1. Only use models developed testing
#' for ahistorical effects.
#' 
#' The default behavior of this function is to estimate fecundity with regards
#' to transitions specified via associated fecundity multipliers in either
#' \code{supplement} or \code{repmatrix}. If both of these fields are left
#' empty, then fecundity will be estimated at full for all transitions leading
#' from reproductive stages to immature and propagule stages. However, if a
#' \code{supplement} is provided and a \code{repmatrix} is not, or if
#' \code{repmatrix} is set to \code{0}, then only fecundity transitions noted in
#' the \code{supplement} will be set to non-zero values. To use the default
#' behavior of setting all reproductive stages to reproduce at full fecundity
#' into immature and propagule stages, but also incorporate given or proxy
#' survival transitions, input those given and proxy transitions through the
#' \code{overwrite} option.
#' 
#' The reproduction matrix (field \code{repmatrix}) may only be supplied as
#' ahistorical. If provided as historical, then \code{flefko2()} will fail and
#' produce an error.
#' 
#' Users may at times wish to estimate MPMs using a dataset incorporating
#' multiple patches or subpopulations, but without discriminating between those
#' patches or subpopulations. Should the aim of analysis be a general MPM that
#' does not distinguish these patches or subpopulations, the
#' \code{modelsearch()} run should not include patch terms.
#'
#' Input options including multiple variable names must be entered in the order
#' of variables in occasion \emph{t}+1 and \emph{t}. Rearranging the order will
#' lead to erroneous calculations, and may lead to fatal errors.
#'
#' Care should be taken to match the random status of year and patch to the
#' states of those variables within the \code{modelsuite}. If they do not match,
#' then they will be treated as zeroes in vital rate estimation.
#' 
#' The \code{ipm_method} function gives the option of using two different means
#' of estimating the probability of size transition. The midpoint method
#' (\code{"midpoint"}) refers to the method in which the probability is
#' estimated by first estimating the probability associated with transition from
#' the exact size at the midpoint of the size class using the corresponding
#' probability density function, and then multiplying that value by the bin
#' width of the size class. Doak et al. 2021 (Ecological Monographs) noted that
#' this method can produce biased results, with total size transitions
#' associated with a specific size not totaling to 1.0 and even specific size
#' transition probabilities capable of being estimated at values greater than
#' 1.0. The alternative and default method, \code{"CDF"}, uses the corresponding
#' cumulative density function to estimate the probability of size transition as
#' the cumulative probability of size transition at the greater limit of the
#' size class minus the cumulative probability of size transition at the lower
#' limit of the size class. The latter method avoids this bias. Note, however,
#' that both methods are exact and unbiased for negative binomial and Poisson
#' distributions.
#' 
#' Under the Gaussian and gamma size distributions, the number of estimated
#' parameters may differ between the two \code{ipm_method} settings. Because
#' the midpoint method has a tendency to incorporate upward bias in the
#' estimation of size transition probabilities, it is more likely to yield non-
#' zero values when the true probability is extremely close to 0. This will
#' result in the \code{summary.lefkoMat} function yielding higher numbers of
#' estimated parameters than the \code{ipm_method = "CDF"} yields in some cases.
#' 
#' Using the \code{err_check} option will produce a matrix of 7 columns, each
#' characterizing a different vital rate. The product of each row yields an
#' element in the associated \code{U} matrix. The number and order of elements
#' in each column of this matrix matches the associated matrix in column vector
#' format. Use of this option is generally for the purposes of debugging code.
#' 
#' Individual covariates are treated as categorical only if they are set as
#' random terms. Fixed categorical individual covariates are currently not
#' allowed. However, such terms may be supplied if the \code{modelsuite} option
#' is set to a \code{vrm_input} object. In that case, the user should also set
#' the logical random switch for the individual covariate to be used to 
#' \code{TRUE} (e.g., \code{random.inda = TRUE}).
#'
#' @seealso \code{\link{mpm_create}()}
#' @seealso \code{\link{flefko3}()}
#' @seealso \code{\link{aflefko2}()}
#' @seealso \code{\link{arlefko2}()}
#' @seealso \code{\link{fleslie}()}
#' @seealso \code{\link{rlefko3}()}
#' @seealso \code{\link{rlefko2}()}
#' @seealso \code{\link{rleslie}()}
#' 
#' @examples
#' \donttest{
#' # Lathyrus example
#' data(lathyrus)
#' 
#' sizevector <- c(0, 4.6, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8,
#'   9)
#' stagevector <- c("Sd", "Sdl", "Dorm", "Sz1nr", "Sz2nr", "Sz3nr", "Sz4nr", 
#'   "Sz5nr", "Sz6nr", "Sz7nr", "Sz8nr", "Sz9nr", "Sz1r", "Sz2r", "Sz3r", 
#'   "Sz4r", "Sz5r", "Sz6r", "Sz7r", "Sz8r", "Sz9r")
#' repvector <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' obsvector <- c(0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' matvector <- c(0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' immvector <- c(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#'   0)
#' indataset <- c(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' binvec <- c(0, 4.6, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
#'   0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5)
#' 
#' lathframeln <- sf_create(sizes = sizevector, stagenames = stagevector, 
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector,
#'   immstatus = immvector, indataset = indataset, binhalfwidth = binvec,
#'   propstatus = propvector)
#' 
#' lathvertln <- verticalize3(lathyrus, noyears = 4, firstyear = 1988, 
#'   patchidcol = "SUBPLOT", individcol = "GENET", blocksize = 9,
#'   juvcol = "Seedling1988", sizeacol = "lnVol88", repstracol = "Intactseed88",
#'   fecacol = "Intactseed88", deadacol = "Dead1988", 
#'   nonobsacol = "Dormant1988", stageassign = lathframeln,
#'   stagesize = "sizea", censorcol = "Missing1988", censorkeep = NA,
#'   NAas0 = TRUE, censor = TRUE)
#' 
#' lathvertln$feca2 <- round(lathvertln$feca2)
#' lathvertln$feca1 <- round(lathvertln$feca1)
#' lathvertln$feca3 <- round(lathvertln$feca3)
#' 
#' lathmodelsln2 <- modelsearch(lathvertln, historical = FALSE, 
#'   approach = "mixed", suite = "main",
#'   vitalrates = c("surv", "obs", "size", "repst", "fec"), juvestimate = "Sdl",
#'   bestfit = "AICc&k", sizedist = "gaussian", fecdist = "poisson",
#'   indiv = "individ", patch = "patchid", year = "year2",
#'   year.as.random = TRUE, patch.as.random = TRUE, show.model.tables = TRUE,
#'   quiet = "partial")
#' 
#' # Here we use supplemental to provide overwrite and reproductive info
#' lathsupp2 <- supplemental(stage3 = c("Sd", "Sdl", "Sd", "Sdl"), 
#'   stage2 = c("Sd", "Sd", "rep", "rep"),
#'   givenrate = c(0.345, 0.054, NA, NA),
#'   multiplier = c(NA, NA, 0.345, 0.054),
#'   type = c(1, 1, 3, 3), stageframe = lathframeln, historical = FALSE)
#' 
#' lathmat2ln <- flefko2(year = "all", patch = "all", stageframe = lathframeln, 
#'   modelsuite = lathmodelsln2, data = lathvertln, supplement = lathsupp2,
#'   reduce = FALSE)
#' 
#' #Cypripedium example using three size metrics for classification
#' data(cypdata)
#' sizevector_f <- c(0, 0, 0, 0, 0, 0, seq(1, 12, by = 1), seq(0, 9, by = 1),
#'   seq(0, 8, by = 1), seq(0, 7, by = 1), seq(0, 6, by = 1), seq(0, 5, by = 1),
#'   seq(0, 4, by = 1), seq(0, 3, by = 1), 0, 1, 2, 0, 1, 0, 
#'   0, 0, 1, 0)
#' sizebvector_f <- c(0, 0, 0, 0, 0, 0, rep(0, 12), rep(1, 10), rep(2, 9),
#'   rep(3, 8), rep(4, 7), rep(5, 6), rep(6, 5), rep(7, 4), rep(8, 3), 9, 9, 10, 
#'   0, 1, 1, 2)
#' sizecvector_f <- c(0, 0, 0, 0, 0, 0, rep(0, 12), rep(0, 10), rep(0, 9),
#'   rep(0, 8), rep(0, 7), rep(0, 6), rep(0, 5), rep(0, 4), 0, 0, 0, 0, 0, 0, 
#'   1, 1, 1, 1)
#' stagevector_f <- c("DS", "P1", "P2", "P3", "Sdl", "Dorm", "V1 I0 D0",
#'   "V2 I0 D0", "V3 I0 D0", "V4 I0 D0", "V5 I0 D0", "V6 I0 D0", "V7 I0 D0",
#'   "V8 I0 D0", "V9 I0 D0", "V10 I0 D0", "V11 I0 D0", "V12 I0 D0", "V0 I1 D0",
#'   "V1 I1 D0", "V2 I1 D0", "V3 I1 D0", "V4 I1 D0", "V5 I1 D0", "V6 I1 D0",
#'   "V7 I1 D0", "V8 I1 D0", "V9 I1 D0", "V0 I2 D0", "V1 I2 D0", "V2 I2 D0",
#'   "V3 I2 D0", "V4 I2 D0", "V5 I2 D0", "V6 I2 D0", "V7 I2 D0", "V8 I2 D0",
#'   "V0 I3 D0", "V1 I3 D0", "V2 I3 D0", "V3 I3 D0", "V4 I3 D0", "V5 I3 D0",
#'   "V6 I3 D0", "V7 I3 D0", "V0 I4 D0", "V1 I4 D0", "V2 I4 D0", "V3 I4 D0",
#'   "V4 I4 D0", "V5 I4 D0", "V6 I4 D0", "V0 I5 D0", "V1 I5 D0", "V2 I5 D0",
#'   "V3 I5 D0", "V4 I5 D0", "V5 I5 D0", "V0 I6 D0", "V1 I6 D0", "V2 I6 D0",
#'   "V3 I6 D0", "V4 I6 D0", "V0 I7 D0", "V1 I7 D0", "V2 I7 D0", "V3 I7 D0",
#'   "V0 I8 D0", "V1 I8 D0", "V2 I8 D0", "V0 I9 D0", "V1 I9 D0", "V0 I10 D0",
#'   "V0 I0 D1", "V0 I1 D1", "V1 I1 D1", "V0 I2 D1")
#' repvector_f <- c(0, 0, 0, 0, 0, rep(0, 13), rep(1, 59))
#' obsvector_f <- c(0, 0, 0, 0, 0, 0, rep(1, 71))
#' matvector_f <- c(0, 0, 0, 0, 0, rep(1, 72))
#' immvector_f <- c(0, 1, 1, 1, 1, rep(0, 72))
#' propvector_f <- c(1, rep(0, 76))
#' indataset_f <- c(0, 0, 0, 0, 0, rep(1, 72))
#' binvec_f <- c(0, 0, 0, 0, 0, rep(0.5, 72))
#' binbvec_f <- c(0, 0, 0, 0, 0, rep(0.5, 72))
#' bincvec_f <- c(0, 0, 0, 0, 0, rep(0.5, 72))
#' 
#' vertframe_f <- sf_create(sizes = sizevector_f, sizesb = sizebvector_f,
#'   sizesc = sizecvector_f, stagenames = stagevector_f, repstatus = repvector_f,
#'   obsstatus = obsvector_f, propstatus = propvector_f, immstatus = immvector_f,
#'   matstatus = matvector_f, indataset = indataset_f, binhalfwidth = binvec_f,
#'   binhalfwidthb = binbvec_f, binhalfwidthc = bincvec_f)
#' 
#' vert_data_f <- verticalize3(cypdata, noyears = 6, firstyear = 2004,
#'   individcol = "plantid", blocksize = 4, sizeacol = "Veg.04",
#'   sizebcol = "Inf.04", sizeccol = "Inf2.04", repstracol = "Inf.04",
#'   repstrbcol = "Inf2.04", fecacol = "Pod.04", censorcol = "censor",
#'   censorkeep = 1, censorRepeat = FALSE, stageassign = vertframe_f,
#'   stagesize = "sizeabc", NAas0 = TRUE, censor = FALSE)
#' 
#' vertmodels2f <- modelsearch(vert_data_f, historical = FALSE, suite = "main", 
#'   sizeb = c("sizeb3", "sizeb2", "sizeb1"), sizec = c("sizec3", "sizec2", "sizec1"),
#'   approach = "glm", vitalrates = c("surv", "obs", "size", "repst", "fec"),
#'   sizedist = "negbin", sizebdist = "poisson", sizecdist = "poisson",
#'   fecdist = "poisson", patch.as.random = TRUE, year.as.random = TRUE,
#'   quiet = "partial")
#' 
#' vertsupp2f <- supplemental(stage3 = c("DS", "P1", "P2", "P3", "Sdl", "Sdl",
#'     "Dorm", "V1 I0 D0", "V2 I0 D0", "V3 I0 D0", "DS", "P1"),
#'   stage2 = c("DS", "DS", "P1", "P2", "P3", "Sdl", "Sdl", "Sdl", "Sdl", "Sdl",
#'     "rep", "rep"), 
#'   eststage3 = c(NA, NA, NA, NA, NA, NA, "Dorm", "V1 I0 D0", "V2 I0 D0",
#'     "V3 I0 D0", NA, NA), 
#'   eststage2 = c(NA, NA, NA, NA, NA, NA, "V1 I0 D0", "V1 I0 D0", "V1 I0 D0",
#'     "V1 I0 D0", NA, NA), 
#'   givenrate = c(0.10, 0.20, 0.20, 0.20, 0.25, 0.40, NA, NA, NA, NA, NA, NA),
#'   multiplier = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.5 * 5000, 0.5 * 5000),
#'   type =c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3), stageframe = vertframe_f,
#'   historical = FALSE)
#' 
#' vert_mats_f2 <- flefko2(stageframe = vertframe_f, supplement = vertsupp2f, 
#'   data = vert_data_f, modelsuite = vertmodels2f)
#' }
#' 
#' @export
flefko2 <- function(year = "all", patch = "all", stageframe, supplement = NULL,
  repmatrix = NULL, overwrite = NULL, data = NULL, modelsuite = NULL,
  surv_model = NULL, obs_model = NULL, size_model = NULL, sizeb_model = NULL,
  sizec_model = NULL, repst_model = NULL, fec_model = NULL, jsurv_model = NULL,
  jobs_model = NULL, jsize_model = NULL, jsizeb_model = NULL,
  jsizec_model = NULL, jrepst_model = NULL, jmatst_model = NULL,
  paramnames = NULL, inda = NULL, indb = NULL, indc = NULL, surv_dev = 0,
  obs_dev = 0, size_dev = 0, sizeb_dev = 0, sizec_dev = 0, repst_dev = 0,
  fec_dev = 0, jsurv_dev = 0, jobs_dev = 0, jsize_dev = 0, jsizeb_dev = 0,
  jsizec_dev = 0, jrepst_dev = 0, jmatst_dev = 0, density = NA, fecmod = 1.0,
  random.inda = FALSE, random.indb = FALSE, random.indc = FALSE, negfec = FALSE,
  ipm_method = "CDF", reduce = FALSE, simple = FALSE, err_check = FALSE,
  exp_tol = 700, theta_tol = 100000000, sparse_output = FALSE) {
  
  cdf <- TRUE
  
  ipm_method <- tolower(ipm_method)
  if (grepl("mi", ipm_method)) {
    cdf <- FALSE
  }
  
  devterms <- c(surv_dev, obs_dev, size_dev, sizeb_dev, sizec_dev, repst_dev,
    fec_dev, jsurv_dev, jobs_dev, jsize_dev, jsizeb_dev, jsizec_dev, jrepst_dev,
    jmatst_dev)
  
  if (is.null(modelsuite)) {
    if (!is.null(surv_model)) {
      modelsuite <- list(surv_model = surv_model, obs_model = obs_model,
        size_model = size_model, sizeb_model = sizeb_model,
        sizec_model = sizec_model, repst_model = repst_model,
        fec_model = fec_model, jsurv_model = jsurv_model,
        jobs_model = jobs_model, jsize_model = jsize_model,
        jsizeb_model = jsizeb_model, jsizec_model = jsizec_model,
        jrepst_model = jrepst_model, jmatst_model = jmatst_model)
      if (!is.null(paramnames)) modelsuite$paramnames <- paramnames
    }
  }
  
  output <- mpm_create(historical = FALSE, stage = TRUE, age = FALSE,
    devries = FALSE, reduce = reduce, data = data, year = year, patch = patch,
    stageframe = stageframe, supplement = supplement, overwrite = overwrite,
    repmatrix = repmatrix, modelsuite = modelsuite, paramnames = paramnames,
    inda = inda, indb = indb, indc = indc, dev_terms = devterms,
    density = density, fecmod = fecmod, CDF = cdf, random_inda = random.inda,
    random_indb = random.indb, random_indc = random.indc, negfec = negfec,
    exp_tol = exp_tol, theta_tol = theta_tol, simple = simple,
    err_check = err_check, sparse_output = sparse_output)
  
  return(output)
}

#' Create Function-based Ahistorical Age x Stage Matrix Projection Model
#'
#' Function \code{aflefko2()} returns ahistorical age x stage MPMs corresponding
#' to the patches and occasions given, including the associated component
#' transition and fecundity matrices, data frames detailing the characteristics
#' of ahistorical stages and the exact age-stage combinations corresponding to
#' rows and columns in estimated matrices, and a data frame characterizing the
#' patch and occasion combinations corresponding to these matrices.
#' 
#' @name aflefko2
#' 
#' @param year A variable corresponding to the observation occasion, or a set
#' of such values, given in values associated with the year term used in linear 
#' model development. Defaults to \code{"all"}, in which case matrices will be
#' estimated for all occasions.
#' @param patch A variable designating which patches or subpopulations will have
#' matrices estimated. Defaults to \code{"all"}, but can also be set to specific
#' patch names or a vector thereof.
#' @param stageframe An object of class \code{stageframe}. These objects are
#' generated by function \code{\link{sf_create}()}, and include information on
#' the size, observation status, propagule status, reproduction status,
#' immaturity status, maturity status, stage group, size bin widths, and other
#' key characteristics of each ahistorical stage.
#' @param supplement An optional data frame of class \code{lefkoSD} that
#' provides supplemental data that should be incorporated into the MPM. Three
#' kinds of data may be integrated this way: transitions to be estimated via the
#' use of proxy transitions, transition overwrites from the literature or
#' supplemental studies, and transition multipliers for survival and fecundity.
#' This data frame should be produced using the \code{\link{supplemental}()}
#' function. Can be used in place of or in addition to an overwrite table (see 
#' \code{overwrite} below) and a reproduction matrix (see \code{repmatrix}
#' below).
#' @param repmatrix An optional reproduction matrix. This matrix is composed
#' mostly of \code{0}s, with non-zero entries acting as element identifiers and
#' multipliers for fecundity (with \code{1} equaling full fecundity). If left
#' blank, and no \code{supplement} is provided, then \code{aflefko2()} will
#' assume that all stages marked as reproductive produce offspring at 1x that of
#' estimated fecundity, and that offspring production will yield the first stage
#' noted as propagule or immature. Must be the dimensions of an ahistorical
#' stage-based matrix.
#' @param overwrite An optional data frame developed with the
#' \code{\link{overwrite}()} function describing transitions to be overwritten
#' either with given values or with other estimated transitions. Note that this
#' function supplements overwrite data provided in \code{supplement}.
#' @param data  The historical vertical demographic data frame used to estimate
#' vital rates (class \code{hfvdata}), which is required to initialize times and
#' patches properly. Variable names should correspond to the naming conventions
#' in \code{\link{verticalize3}()} and \code{\link{historicalize3}()}. Not
#' required if option \code{modelsuite} is set to a \code{vrm_input} object.
#' @param modelsuite One of two kinds of lists. The first is a \code{lefkoMod}
#' object holding the vital rate models and associated metadata. Alternatively,
#' an object of class \code{vrm_input} may be provided. If given, then
#' \code{surv_model}, \code{obs_model}, \code{size_model}, \code{sizeb_model},
#' \code{sizec_model}, \code{repst_model}, \code{fec_model}, \code{jsurv_model},
#' \code{jobs_model}, \code{jsize_model}, \code{jsizeb_model},
#' \code{jsizec_model}, \code{jrepst_model}, \code{jmatst_model}, and
#' \code{paramnames} are not required. No models should include size or
#' reproductive status in occasion \emph{t}-1. Although this is optional input,
#' it is recommended, and without it all vital rate model inputs (named
#' \code{XX_model}) are required.
#' @param surv_model A linear model predicting survival probability. This can 
#' be a model of class \code{glm} or \code{glmer}, and requires a predicted
#' binomial variable under a logit link. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param obs_model A linear model predicting sprouting or observation
#' probability. This can be a model of class \code{glm} or \code{glmer}, and
#' requires a predicted binomial variable under a logit link. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param size_model A linear model predicting primary size. This can be a model
#' of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param sizeb_model A linear model predicting secondary size. This can be a
#' model of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param sizec_model A linear model predicting tertiary size. This can be a
#' model of class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param repst_model A linear model predicting reproduction probability. This 
#' can be a model of class \code{glm} or \code{glmer}, and requires a predicted
#' binomial variable under a logit link. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param fec_model A linear model predicting fecundity. This can be a model of
#' class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl}, \code{vglm},
#' \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is provided. This
#' model must have been developed in a modeling exercise testing only the
#' impacts of occasion \emph{t}.
#' @param jsurv_model A linear model predicting juvenile survival probability.
#' This can be a model of class \code{glm} or \code{glmer}, and requires a
#' predicted binomial variable under a logit link. Ignored if \code{modelsuite}
#' is provided. This model must have been developed in a modeling exercise
#' testing only the impacts of occasion \emph{t}.
#' @param jobs_model A linear model predicting juvenile sprouting or observation
#' probability. This can be a model of class \code{glm} or \code{glmer}, and
#' requires a predicted binomial variable under a logit link. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param jsize_model A linear model predicting juvenile primary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param jsizeb_model A linear model predicting juvenile secondary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param jsizec_model A linear model predicting juvenile tertiary size. This
#' can be a model of class \code{glm}, \code{glmer}, \code{glmmTMB},
#' \code{zeroinfl}, \code{vglm}, \code{lm}, or \code{lmer}. Ignored if
#' \code{modelsuite} is provided. This model must have been developed in a
#' modeling exercise testing only the impacts of occasion \emph{t}.
#' @param jrepst_model A linear model predicting reproduction probability of a 
#' mature individual that was immature in time \emph{t}. This can be a model
#' of class \code{glm} or \code{glmer}, and requires a predicted binomial
#' variable under a logit link. Ignored if \code{modelsuite} is provided. This
#' model must have been developed in a modeling exercise testing only the
#' impacts of occasion \emph{t}.
#' @param jmatst_model A linear model predicting maturity probability of an 
#' individual that was immature in time \emph{t}. This can be a model of class
#' \code{glm} or \code{glmer}, and requires a predicted binomial variable under
#' a logit link. Ignored if \code{modelsuite} is provided. This model must have
#' been developed in a modeling exercise testing only the impacts of occasion
#' \emph{t}.
#' @param paramnames A data frame with three columns, the first describing all
#' terms used in linear modeling, the second (must be called \code{mainparams})
#' giving the general model terms that will be used in matrix creation, and the
#' third showing the equivalent terms used in modeling (must be named
#' \code{modelparams}). Function \code{\link{create_pm}()} can be used to
#' create a skeleton \code{paramnames} object, which can then be edited. Only
#' required if \code{modelsuite} is not supplied.
#' @param inda Can be a single value to use for individual covariate \code{a}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param indb Can be a single value to use for individual covariate \code{b}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param indc Can be a single value to use for individual covariate \code{c}
#' in all matrices, a pair of values to use for times \emph{t} and \emph{t}-1 in
#' historical matrices, or a vector of such values corresponding to each
#' occasion in the dataset. Defaults to \code{NULL}.
#' @param surv_dev A numeric value to be added to the y-intercept in the linear
#' model for survival probability. Defaults to \code{0}.
#' @param obs_dev A numeric value to be added to the y-intercept in the linear
#' model for observation probability. Defaults to \code{0}.
#' @param size_dev A numeric value to be added to the y-intercept in the linear
#' model for primary size. Defaults to \code{0}.
#' @param sizeb_dev A numeric value to be added to the y-intercept in the linear
#' model for secondary size. Defaults to \code{0}.
#' @param sizec_dev A numeric value to be added to the y-intercept in the linear
#' model for tertiary size. Defaults to \code{0}.
#' @param repst_dev A numeric value to be added to the y-intercept in the linear
#' model for probability of reproduction. Defaults to \code{0}.
#' @param fec_dev A numeric value to be added to the y-intercept in the linear
#' model for fecundity. Defaults to \code{0}.
#' @param jsurv_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile survival probability. Defaults to \code{0}.
#' @param jobs_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile observation probability. Defaults to \code{0}.
#' @param jsize_dev A numeric value to be added to the y-intercept in the linear
#' model for juvenile primary size. Defaults to \code{0}.
#' @param jsizeb_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile secondary size. Defaults to \code{0}.
#' @param jsizec_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile tertiary size. Defaults to \code{0}.
#' @param jrepst_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile reproduction probability. Defaults to \code{0}.
#' @param jmatst_dev A numeric value to be added to the y-intercept in the
#' linear model for juvenile maturity probability. Defaults to \code{0}.
#' @param density A numeric value indicating density value to use to propagate
#' matrices. Only needed if density is an explanatory term used in one or more
#' vital rate models. Defaults to \code{NA}.
#' @param fecmod A scalar multiplier of fecundity. Defaults to \code{1.0}.
#' @param random.inda A logical value denoting whether to treat individual
#' covariate \code{a} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param random.indb A logical value denoting whether to treat individual
#' covariate \code{b} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param random.indc A logical value denoting whether to treat individual
#' covariate \code{c} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param final_age The final age to model in the matrix, where the first age
#' will be age 0. Defaults to the maximum age in the dataset.
#' @param continue A logical value designating whether to allow continued
#' survival of individuals past the final age noted in the stageframe, using the 
#' demographic characteristics of the final age. Defaults to \code{TRUE}.
#' @param prebreeding A logical value indicating whether the life history model
#' is a pre-breeding model. Defaults to \code{TRUE}.
#' @param negfec A logical value denoting whether fecundity values estimated to
#' be negative should be reset to \code{0}. Defaults to \code{FALSE}.
#' @param ipm_method A string indicating what method to use to estimate size
#' transition probabilities, if size is treated as continuous. Options include:
#' \code{"midpoint"}, which utilizes the midpoint method; and \code{"CDF"},
#' which uses the cumulative distribution function. Defaults to \code{"CDF"}.
#' @param reduce A logical value denoting whether to remove age-stages
#' associated solely with \code{0} transitions. These are only removed in cases
#' where the associated row and column sums in ALL matrices estimated equal 0. 
#' Defaults to \code{FALSE}.
#' @param simple A logical value indicating whether to produce \code{A},
#' \code{U}, and \code{F} matrices, or only the latter two. Defaults to
#' \code{FALSE}, in which case all three are output.
#' @param err_check A logical value indicating whether to append extra
#' information used in matrix calculation within the output list. Defaults to
#' \code{FALSE}.
#' @param exp_tol A numeric value used to indicate a maximum value to set
#' exponents to in the core kernel to prevent numerical overflow. Defaults to
#' \code{700}.
#' @param theta_tol A numeric value used to indicate a maximum value to theta as
#' used in the negative binomial probability density kernel. Defaults to
#' \code{100000000}, but can be reset to other values during error checking.
#' @param sparse_output A logical value indicating whether to output matrices
#' in sparse format. Defaults to \code{FALSE}, in which case all matrices are
#' output in standard matrix format.
#'
#' @return If all inputs are properly formatted, then this function will return
#' an object of class \code{lefkoMat}, which is a list that holds the matrix
#' projection model and all of its metadata. The structure has the following
#' elements:
#'
#' \item{A}{A list of full projection matrices in order of sorted patches and
#' occasions. All matrices output in R's \code{matrix} class, or in
#' the \code{dgCMatrix} class from the \code{Matrix} package if sparse.}
#' \item{U}{A list of survival transition matrices sorted as in \code{A}. All 
#' matrices output in R's \code{matrix} class, or in the \code{dgCMatrix} class
#' from the \code{Matrix} package if sparse.}
#' \item{F}{A list of fecundity matrices sorted as in \code{A}. All matrices 
#' output in R's \code{matrix} class, or in the \code{dgCMatrix} class from the
#' \code{Matrix} package if sparse.}
#' \item{hstages}{A data frame matrix showing the pairing of ahistorical stages
#' used to create historical stage pairs. Set to \code{NA} for age-by-stage
#' MPMs.}
#' \item{agestages}{A data frame showing the stage number and stage name
#' corresponding to \code{ahstages}, as well as the associated age, of each
#' row in each age-by-stage matrix.}
#' \item{ahstages}{A data frame detailing the characteristics of associated
#' ahistorical stages, in the form of a modified stageframe that includes
#' status as an entry stage through reproduction.}
#' \item{labels}{A data frame giving the patch and year of each matrix in order.
#' In \code{aflefko2()}, only one population may be analyzed at once.}
#' \item{dataqc}{A vector showing the numbers of individuals and rows in the
#' vertical dataset used as input.}
#' \item{matrixqc}{A short vector describing the number of non-zero elements in
#' \code{U} and \code{F} matrices, and the number of annual matrices.}
#' \item{modelqc}{This is the \code{qc} portion of the \code{modelsuite} input.}
#' \item{prob_out}{An optional element only added if \code{err_check = TRUE}.
#' This is a list of vital rate probability matrices, with 7 columns in the
#' order of survival, observation probability, reproduction probability, primary
#' size transition probability, secondary size transition probability, tertiary
#' size transition probability, and probability of juvenile transition to
#' maturity.}
#' \item{allstages}{An optional element only added if \code{err_check = TRUE}.
#' This is a data frame giving the values used to determine each matrix element
#' capable of being estimated.}
#' 
#' @section Notes:
#' Unlike \code{\link{rlefko2}()}, \code{\link{rlefko3}()},
#' \code{\link{arlefko2}()}, and \code{\link{rleslie}()}, this function does not
#' currently distinguish populations. Users wishing to use the same vital rate
#' models across populations should label them as patches (though we do not
#' advise this approach, as populations should typically be treated as
#' statistically independent).
#' 
#' This function will yield incorrect estimates if the models utilized
#' incorporate state in occasion \emph{t}-1. Only use models developed testing
#' for ahistorical effects.
#' 
#' The default behavior of this function is to estimate fecundity with regards
#' to transitions specified via associated fecundity multipliers in either
#' \code{supplement} or \code{repmatrix}. If both of these fields are left
#' empty, then fecundity will be estimated at full for all transitions leading
#' from reproductive stages to immature and propagule stages. However, if a
#' \code{supplement} is provided and a \code{repmatrix} is not, or if
#' \code{repmatrix} is set to 0, then only fecundity transitions noted in the
#' supplement will be set to non-zero values. To use the default behavior of
#' setting all reproductive stages to reproduce at full fecundity into immature
#' and propagule stages but also incorporate given or proxy
#' survival transitions, input those given and proxy transitions through the
#' \code{overwrite} option.
#' 
#' The reproduction matrix (field \code{repmatrix}) may only be supplied as
#' ahistorical. If provided as historical, then \code{aflefko2()} will fail and
#' produce an error.
#' 
#' Stageframes used in this function should include ages for minimum and maximum
#' age for each stage. \code{NA}s are treated as \code{0}s in minimum age, and
#' as \code{final_age} for maximum age.
#' 
#' Users may at times wish to estimate MPMs using a dataset incorporating
#' multiple patches or subpopulations, but without discriminating between those
#' patches or subpopulations. Should the aim of analysis be a general MPM that
#' does not distinguish these patches or subpopulations, the
#' \code{modelsearch()} run should not include patch terms.
#'
#' Input options including multiple variable names must be entered in the order
#' of variables in occasion \emph{t}+1 and \emph{t}. Rearranging the order will
#' lead to erroneous calculations, and may lead to fatal errors.
#'
#' Care should be taken to match the random status of year and patch to the
#' states of those variables within the \code{modelsuite}. If they do not match,
#' then they will be treated as zeroes in vital rate estimation.
#' 
#' The \code{ipm_method} function gives the option of using two different means
#' of estimating the probability of size transition. The midpoint method
#' (\code{"midpoint"}) refers to the method in which the probability is
#' estimated by first estimating the probability associated with transition from
#' the exact size at the midpoint of the size class using the corresponding
#' probability density function, and then multiplying that value by the bin
#' width of the size class. Doak et al. 2021 (Ecological Monographs) noted that
#' this method can produce biased results, with total size transitions
#' associated with a specific size not totaling to 1.0 and even specific size
#' transition probabilities capable of being estimated at values greater than
#' 1.0. The alternative and default method, \code{"CDF"}, uses the corresponding
#' cumulative density function to estimate the probability of size transition as
#' the cumulative probability of size transition at the greater limit of the
#' size class minus the cumulative probability of size transition at the lower
#' limit of the size class. The latter method avoids this bias. Note, however,
#' that both methods are exact and unbiased for the Poisson and negative
#' binomial distributions.
#' 
#' Under the Gaussian and gamma size distributions, the number of estimated
#' parameters may differ between the two \code{ipm_method} settings. Because
#' the midpoint method has a tendency to incorporate upward bias in the
#' estimation of size transition probabilities, it is more likely to yield non-
#' zero values when the true probability is extremely close to 0. This will
#' result in the \code{summary.lefkoMat} function yielding higher numbers of
#' estimated parameters than the \code{ipm_method = "CDF"} yields in some cases.
#' 
#' Using the \code{err_check} option will produce a matrix of 7 columns, each
#' characterizing a different vital rate. The product of each row yields an
#' element in the associated \code{U} matrix. The number and order of elements
#' in each column of this matrix matches the associated matrix in column vector
#' format. Use of this option is generally for the purposes of debugging code.
#' 
#' Individual covariates are treated as categorical only if they are set as
#' random terms. Fixed categorical individual covariates are currently not
#' allowed. However, such terms may be supplied if the \code{modelsuite} option
#' is set to a \code{vrm_input} object. In that case, the user should also set
#' the logical random switch for the individual covariate to be used to 
#' \code{TRUE} (e.g., \code{random.inda = TRUE}).
#'
#' @seealso \code{\link{mpm_create}()}
#' @seealso \code{\link{flefko3}()}
#' @seealso \code{\link{flefko2}()}
#' @seealso \code{\link{fleslie}()}
#' @seealso \code{\link{arlefko2}()}
#' @seealso \code{\link{rlefko3}()}
#' @seealso \code{\link{rlefko2}()}
#' @seealso \code{\link{rleslie}()}
#' 
#' @examples
#' \donttest{
#' data(lathyrus)
#' 
#' sizevector <- c(0, 4.6, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8,
#'   9)
#' stagevector <- c("Sd", "Sdl", "Dorm", "Sz1nr", "Sz2nr", "Sz3nr", "Sz4nr",
#'   "Sz5nr", "Sz6nr", "Sz7nr", "Sz8nr", "Sz9nr", "Sz1r", "Sz2r", "Sz3r",
#'   "Sz4r", "Sz5r", "Sz6r", "Sz7r", "Sz8r", "Sz9r")
#' repvector <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' obsvector <- c(0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' matvector <- c(0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' immvector <- c(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#'   0)
#' indataset <- c(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
#' minima <- c(1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)
#' binvec <- c(0, 4.6, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
#'   0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5)
#' 
#' lathframeln <- sf_create(sizes = sizevector, stagenames = stagevector,
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector,
#'   immstatus = immvector, indataset = indataset, binhalfwidth = binvec,
#'   propstatus = propvector, minage = minima)
#' 
#' lathvertln <- verticalize3(lathyrus, noyears = 4, firstyear = 1988,
#'   patchidcol = "SUBPLOT", individcol = "GENET", blocksize = 9,
#'   juvcol = "Seedling1988", sizeacol = "lnVol88", repstracol = "Intactseed88",
#'   fecacol = "Intactseed88", deadacol = "Dead1988",
#'   nonobsacol = "Dormant1988", stageassign = lathframeln,
#'   stagesize = "sizea", censorcol = "Missing1988", censorkeep = NA,
#'   NAas0 = TRUE, censor = TRUE)
#' 
#' lathvertln$feca2 <- round(lathvertln$feca2)
#' lathvertln$feca1 <- round(lathvertln$feca1)
#' lathvertln$feca3 <- round(lathvertln$feca3)
#' 
#' lathmodelsln2 <- modelsearch(lathvertln, historical = FALSE,
#'   approach = "mixed", suite = "main",
#'   vitalrates = c("surv", "obs", "size", "repst", "fec"), juvestimate = "Sdl",
#'   bestfit = "AICc&k", sizedist = "gaussian", fecdist = "poisson",
#'   indiv = "individ", patch = "patchid", year = "year2", age = "obsage",
#'   year.as.random = TRUE, patch.as.random = TRUE, show.model.tables = TRUE,
#'   quiet = "partial")
#' 
#' # Here we use supplemental() to provide overwrite and reproductive info
#' lathsupp2 <- supplemental(stage3 = c("Sd", "Sdl", "mat", "Sd", "Sdl"), 
#'   stage2 = c("Sd", "Sd", "Sdl", "rep", "rep"),
#'   eststage3 = c(NA, NA, "mat", NA, NA),
#'   eststage2 = c(NA, NA, "Dorm", NA, NA),
#'   givenrate = c(0.345, 0.054, NA, NA, NA),
#'   multiplier = c(NA, NA, 0.8, 0.345, 0.054), type = c(1, 1, 1, 3, 3),
#'   stageframe = lathframeln, historical = FALSE, agebased = TRUE)
#' 
#' lathmat2age <- aflefko2(year = "all", patch = "all", 
#'   stageframe = lathframeln, modelsuite = lathmodelsln2, data = lathvertln,
#'   supplement = lathsupp2, final_age = 3, continue = TRUE, reduce = FALSE)
#' 
#' }
#' @export
aflefko2 <- function(year = "all", patch = "all", stageframe, supplement = NULL,
  repmatrix = NULL, overwrite = NULL, data = NULL, modelsuite = NULL,
  surv_model = NULL, obs_model = NULL, size_model = NULL, sizeb_model = NULL,
  sizec_model = NULL, repst_model = NULL, fec_model = NULL, jsurv_model = NULL,
  jobs_model = NULL, jsize_model = NULL, jsizeb_model = NULL,
  jsizec_model = NULL, jrepst_model = NULL, jmatst_model = NULL,
  paramnames = NULL, inda = NULL, indb = NULL, indc = NULL, surv_dev = 0,
  obs_dev = 0, size_dev = 0, sizeb_dev = 0, sizec_dev = 0, repst_dev = 0,
  fec_dev = 0, jsurv_dev = 0, jobs_dev = 0, jsize_dev = 0, jsizeb_dev = 0,
  jsizec_dev = 0, jrepst_dev = 0, jmatst_dev = 0, density = NA, fecmod = 1.0,
  random.inda = FALSE, random.indb = FALSE, random.indc = FALSE, final_age = NA,
  continue = TRUE, prebreeding = TRUE, negfec = FALSE, ipm_method = "CDF",
  reduce = FALSE, simple = FALSE, err_check = FALSE, exp_tol = 700,
  theta_tol = 100000000, sparse_output = FALSE) {
  
  cdf <- TRUE
  
  ipm_method <- tolower(ipm_method)
  if (grepl("mi", ipm_method)) {
    cdf <- FALSE
  }
  
  devterms <- c(surv_dev, obs_dev, size_dev, sizeb_dev, sizec_dev, repst_dev,
    fec_dev, jsurv_dev, jobs_dev, jsize_dev, jsizeb_dev, jsizec_dev, jrepst_dev,
    jmatst_dev)
  
  if (is.null(modelsuite)) {
    if (!is.null(surv_model)) {
      modelsuite <- list(surv_model = surv_model, obs_model = obs_model,
        size_model = size_model, sizeb_model = sizeb_model,
        sizec_model = sizec_model, repst_model = repst_model,
        fec_model = fec_model, jsurv_model = jsurv_model,
        jobs_model = jobs_model, jsize_model = jsize_model,
        jsizeb_model = jsizeb_model, jsizec_model = jsizec_model,
        jrepst_model = jrepst_model, jmatst_model = jmatst_model)
      if (!is.null(paramnames)) modelsuite$paramnames <- paramnames
    }
  }
  
  output <- mpm_create(historical = FALSE, stage = TRUE, age = TRUE,
    devries = FALSE, reduce = reduce, data = data, year = year, patch = patch,
    stageframe = stageframe, supplement = supplement, overwrite = overwrite,
    repmatrix = repmatrix, modelsuite = modelsuite, paramnames = paramnames,
    inda = inda, indb = indb, indc = indc, dev_terms = devterms,
    density = density, fecmod = fecmod, CDF = cdf, random_inda = random.inda,
    random_indb = random.indb, random_indc = random.indc, negfec = negfec,
    exp_tol = exp_tol, theta_tol = theta_tol, last_age = final_age,
    cont = continue, prebreeding = prebreeding, simple = simple,
    err_check = err_check, sparse_output = sparse_output)
  
  return(output)
}

#' Create Function-based Age-based (Leslie) Matrix Projection Model
#'
#' Function \code{fleslie()} returns age-based (Leslie) MPMs corresponding to
#' the patches and occasions given, including the associated component
#' transition and fecundity matrices, data frames detailing the characteristics
#' of the exact ages corresponding to rows and columns in estimated matrices,
#' and a data frame characterizing the patch and occasion combinations
#' corresponding to these matrices.
#' 
#' @name fleslie
#' 
#' @param year A variable corresponding to observation occasion, or a set
#' of such values, given in values associated with the year term used in linear 
#' model development. Defaults to \code{"all"}, in which case matrices will be
#' estimated for all occasions.
#' @param patch A variable designating which patches or subpopulations will have
#' matrices estimated. Defaults to \code{"all"}, but can also be set to specific
#' patch names or a vector thereof.
#' @param prebreeding A logical value indicating whether the life history model
#' is a pre-breeding model. Defaults to \code{TRUE}.
#' @param data The historical vertical demographic data frame used to estimate
#' vital rates (class \code{hfvdata}). The original data frame is generally
#' required in order to initialize occasions and patches properly, and to assess
#' the range of ages observed in the population. Not required if option
#' \code{modelsuite} is set to a \code{vrm_input} object.
#' @param modelsuite One of two optional lists. THe first is an optional
#' \code{lefkoMod} object holding the vital rate models. Alternatively,
#' an object of class \code{vrm_input} may be provided. If given, then
#' \code{surv_model}, \code{fec_model}, and \code{paramnames} are not required.
#' No models should include size or reproductive status in any occasion, nor
#' should they include any variable for occasion \emph{t}-1. Note that the
#' modelsuite must have been created from a \code{modelsearch()} run in which
#' \code{vitalrates = c("surv", "fec")} and the \code{suite} option was set to
#' either \code{age} or \code{cons}.
#' @param surv_model A linear model predicting survival probability. This can be
#' a model of class \code{glm} or \code{glmer}, and requires a predicted
#' binomial variable under a logit link. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param fec_model A linear model predicting fecundity. This can be a model of
#' class \code{glm}, \code{glmer}, \code{glmmTMB}, \code{zeroinfl},
#' \code{vglm}, \code{lm}, or \code{lmer}. Ignored if \code{modelsuite} is
#' provided. This model must have been developed in a modeling exercise testing
#' only the impacts of occasion \emph{t}.
#' @param paramnames  A data frame with three columns, the first describing all
#' terms used in linear modeling, the second (must be called \code{mainparams})
#' giving the general model terms that will be used in matrix creation, and the
#' third showing the equivalent terms used in modeling (must be named
#' \code{modelparams}). Function \code{\link{create_pm}()} can be used to
#' create a skeleton \code{paramnames} object, which can then be edited. Only
#' required if \code{modelsuite} is not supplied.
#' @param supplement An optional data frame of class \code{lefkoSD} that
#' provides supplemental data that should be incorporated into the MPM. Three
#' kinds of data may be integrated this way: transitions to be estimated via the
#' use of proxy transitions, transition overwrites from the literature or
#' supplemental studies, and transition multipliers for survival and fecundity.
#' This data frame should be produced using the \code{\link{supplemental}()}
#' function.
#' @param start_age The age from which to start the matrix. Defaults to
#' \code{NA}, in which case age \code{1} is used if \code{prebreeding = TRUE},
#' and age \code{0} is used if \code{prebreeding = FALSE}.
#' @param last_age The final age to use in the matrix. Defaults to \code{NA}, in
#' which case the highest age in the dataset is used.
#' @param fecage_min The minimum age at which reproduction is possible. Defaults
#' to \code{NA}, which is interpreted to mean that fecundity should be assessed
#' starting in the minimum age observed in the dataset.
#' @param fecage_max The maximum age at which reproduction is possible. Defaults
#' to \code{NA}, which is interpreted to mean that fecundity should be assessed
#' until the final observed age.
#' @param continue A logical value designating whether to allow continued
#' survival of individuals past the final age noted in the stageframe, using the 
#' demographic characteristics of the final age. Defaults to \code{TRUE}.
#' @param inda Can be a single value to use for individual covariate \code{a}
#' in all matrices, or a vector of such values corresponding to each occasion in
#' the dataset. Defaults to \code{NULL}.
#' @param indb Can be a single value to use for individual covariate \code{b}
#' in all matrices, or a vector of such values corresponding to each occasion in
#' the dataset. Defaults to \code{NULL}.
#' @param indc Can be a single value to use for individual covariate \code{c}
#' in all matrices, or a vector of such values corresponding to each occasion in
#' the dataset. Defaults to \code{NULL}.
#' @param surv_dev A numeric value to be added to the y-intercept in the linear
#' model for survival probability. Defaults to \code{0}.
#' @param fec_dev A numeric value to be added to the y-intercept in the linear
#' model for fecundity. Defaults to \code{0}.
#' @param density A numeric value indicating density value to use to propagate
#' matrices. Only needed if density is an explanatory term used in linear
#' models. Defaults to \code{NA}.
#' @param fecmod A scalar multiplier of fecundity. Defaults to \code{1.0}.
#' @param random.inda A logical value denoting whether to treat individual
#' covariate \code{a} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param random.indb A logical value denoting whether to treat individual
#' covariate \code{b} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param random.indc A logical value denoting whether to treat individual
#' covariate \code{c} as a random, categorical variable. Otherwise is treated as
#' a fixed, numeric variable. Defaults to \code{FALSE}.
#' @param negfec A logical value denoting whether fecundity values estimated to
#' be negative should be reset to \code{0}. Defaults to \code{FALSE}.
#' @param reduce A logical value denoting whether to remove ages associated
#' solely with \code{0} transitions. These are only removed in cases where the
#' associated row and column sums in ALL matrices estimated equal 0. Defaults to
#' \code{FALSE}, and should generally not be used in age-based MPMs.
#' @param simple A logical value indicating whether to produce \code{A},
#' \code{U}, and \code{F} matrices, or only the latter two. Defaults to
#' \code{FALSE}, in which case all three are output.
#' @param err_check A logical value indicating whether to append extra
#' information used in matrix calculation within the output list. Defaults to
#' \code{FALSE}.
#' @param exp_tol A numeric value used to indicate a maximum value to set
#' exponents to in the core kernel to prevent numerical overflow. Defaults to
#' \code{700}.
#' @param theta_tol A numeric value used to indicate a maximum value to theta as
#' used in the negative binomial probability density kernel. Defaults to
#' \code{100000000}, but can be reset to other values during error checking.
#' @param sparse_output A logical value indicating whether to output matrices
#' in sparse format. Defaults to \code{FALSE}, in which case all matrices are
#' output in standard matrix format.
#'
#' @return If all inputs are properly formatted, then this function will return
#' an object of class \code{lefkoMat}, which is a list that holds the matrix
#' projection model and all of its metadata. Its structure has the following
#' elements:
#'
#' \item{A}{A list of full projection matrices in order of sorted patches and
#' occasions. All matrices output in R's \code{matrix} class, or in
#' the \code{dgCMatrix} class from the \code{Matrix} package if sparse.}
#' \item{U}{A list of survival transition matrices sorted as in \code{A}. All 
#' matrices output in R's \code{matrix} class, or in the \code{dgCMatrix} class
#' from the \code{Matrix} package if sparse.}
#' \item{F}{A list of fecundity matrices sorted as in \code{A}. All matrices 
#' output in R's \code{matrix} class, or in the \code{dgCMatrix} class from the
#' \code{Matrix} package if sparse.}
#' \item{hstages}{Set to \code{NA} for Leslie MPMs.}
#' \item{agestages}{Set to \code{NA} for Leslie MPMs.}
#' \item{ahstages}{A data frame detailing the characteristics of associated
#' ages, in the form of a modified stageframe including reproduction status.}
#' \item{labels}{A data frame giving the patch and year of each matrix in order.
#' In \code{fleslie()}, only one population may be analyzed at once.}
#' \item{dataqc}{A vector showing the numbers of individuals and rows in the
#' vertical dataset used as input.}
#' \item{matrixqc}{A short vector describing the number of non-zero elements in
#' \code{U} and \code{F} matrices, and the number of annual matrices.}
#' \item{modelqc}{This is the \code{qc} portion of the \code{modelsuite} input.}
#' \item{prob_out}{An optional element only added if \code{err_check = TRUE}.
#' This is a list of vital rate probability matrices, with 7 columns in the
#' order of survival, observation probability, reproduction probability, primary
#' size transition probability, secondary size transition probability, tertiary
#' size transition probability, and probability of juvenile transition to
#' maturity.}
#' 
#' @section Notes:
#' Unlike \code{\link{rlefko2}()}, \code{\link{rlefko3}()},
#' \code{\link{arlefko2}()}, and \code{\link{rleslie}()}, this function does not
#' currently distinguish populations.
#' 
#' This function will yield incorrect estimates if the models utilized
#' incorporate state in occasion \emph{t}-1, or any size or reproductive status
#' terms.
#' 
#' Users may at times wish to estimate MPMs using a dataset incorporating
#' multiple patches or subpopulations, but without discriminating between those
#' patches or subpopulations. Should the aim of analysis be a general MPM that
#' does not distinguish these patches or subpopulations, the
#' \code{modelsearch()} run should not include patch terms.
#'
#' Input options including multiple variable names must be entered in the order
#' of variables in occasion \emph{t}+1 and \emph{t}. Rearranging the order will
#' lead to erroneous calculations, and may lead to fatal errors.
#'
#' Care should be taken to match the random status of year and patch to the
#' states of those variables within the modelsuite. If they do not match, then
#' they will be treated as zeroes in vital rate estimation.
#' 
#' Individual covariates are treated as categorical only if they are set as
#' random terms. Fixed categorical individual covariates are currently not
#' allowed. However, such terms may be supplied if the \code{modelsuite} option
#' is set to a \code{vrm_input} object. In that case, the user should also set
#' the logical random switch for the individual covariate to be used to 
#' \code{TRUE} (e.g., \code{random.inda = TRUE}).
#'
#' @seealso \code{\link{mpm_create}()}
#' @seealso \code{\link{flefko3}()}
#' @seealso \code{\link{flefko2}()}
#' @seealso \code{\link{aflefko2}()}
#' @seealso \code{\link{arlefko2}()}
#' @seealso \code{\link{rlefko3}()}
#' @seealso \code{\link{rlefko2}()}
#' @seealso \code{\link{rleslie}()}
#' 
#' @examples
#' \donttest{
#' data(lathyrus)
#' 
#' lathvert_base <- verticalize3(lathyrus, noyears = 4, firstyear = 1988,
#'   patchidcol = "SUBPLOT", individcol = "GENET", blocksize = 9,
#'   sizeacol = "Volume88", repstracol = "FCODE88", fecacol = "Intactseed88",
#'   deadacol = "Dead1988", censorcol = "Missing1988", censorkeep = NA,
#'   censor = TRUE, NRasRep = TRUE, NOasObs = TRUE)
#' 
#' lathvert_base$feca3 <- round(lathvert_base$feca3)
#' lathvert_base$feca2 <- round(lathvert_base$feca2)
#' lathvert_base$feca1 <- round(lathvert_base$feca1)
#' 
#' lathvert_age <- subset(lathvert_base, firstseen > 1988)
#' 
#' lathmodels2_age <- modelsearch(lathvert_age, historical = FALSE,
#'   approach = "mixed", suite = "cons", bestfit = "AICc&k", age = "obsage",
#'   vitalrates = c("surv", "fec"), fecdist = "poisson", indiv = "individ",
#'   year = "year2", show.model.tables = TRUE, quiet = "partial")
#' 
#' lathmat2fleslie <- fleslie(year = "all", data = lathvert_age,
#'   modelsuite = lathmodels2_age, fecage_min = 1)
#' }
#' @export
fleslie <- function(year = "all", patch = NULL, prebreeding = TRUE,
  data = NULL, modelsuite = NULL, surv_model = NULL, fec_model = NULL,
  paramnames = NULL, supplement = NULL, start_age = NA, last_age = NA,
  fecage_min = NA, fecage_max = NA, continue = TRUE, inda = NULL, indb = NULL,
  indc = NULL, surv_dev = 0, fec_dev = 0, density = NA, fecmod = 1.0,
  random.inda = FALSE, random.indb = FALSE, random.indc = FALSE, negfec = FALSE,
  reduce = FALSE, simple = FALSE, err_check = FALSE, exp_tol = 700,
  theta_tol = 100000000, sparse_output = FALSE) {
  
  devterms <- c(surv_dev, fec_dev)
  
  if (is.null(modelsuite)) {
    if (!is.null(surv_model)) {
      modelsuite <- list(surv_model = surv_model, obs_model = NULL,
        size_model = NULL, sizeb_model = NULL, sizec_model = NULL,
        repst_model = NULL, fec_model = fec_model, jsurv_model = NULL,
        jobs_model = NULL, jsize_model = NULL, jsizeb_model = NULL,
        jsizec_model = NULL, jrepst_model = NULL, jmatst_model = NULL)
      if (!is.null(paramnames)) modelsuite$paramnames <- paramnames
    }
  }
  
  output <- mpm_create(historical = FALSE, stage = FALSE, age = TRUE,
    devries = FALSE, reduce = reduce, data = data, year = year, patch = patch,
    modelsuite = modelsuite, paramnames = paramnames, supplement = supplement,
    inda = inda, indb = indb, indc = indc, dev_terms = devterms,
    density = density, fecmod = fecmod, random_inda = random.inda,
    random_indb = random.indb, random_indc = random.indc, negfec = negfec,
    exp_tol = exp_tol, theta_tol = theta_tol, start_age = start_age,
    last_age = last_age, fecage_min = fecage_min, fecage_max = fecage_max,
    cont = continue, prebreeding = prebreeding, simple = simple, 
    err_check = err_check, sparse_output = sparse_output)
  
  return(output)
}

#' Create Raw Historical Matrix Projection Model
#' 
#' Function \code{rlefko3()} returns raw historical MPMs, including the
#' associated component transition and fecundity matrices, data frames
#' describing the ahistorical stages used and the historical paired stages, and
#' a data frame describing the population, patch, and occasion time associated
#' with each matrix.
#' 
#' @name rlefko3
#' 
#' @param data  A vertical demographic data frame, with variables corresponding 
#' to the naming conventions in \code{\link{verticalize3}()} and
#' \code{\link{historicalize3}()}.
#' @param stageframe A stageframe object that includes information on the size,
#' observation status, propagule status, reproduction status, immaturity status,
#' and maturity status of each ahistorical stage.
#' @param year A variable corresponding to observation occasion, or a set of
#' such values, given in values associated with the \code{year} term used in
#' vital rate model development. Can also equal \code{"all"}, in which case
#' matrices will be estimated for all occasions. Defaults to \code{"all"}.
#' @param pop A variable designating which populations will have matrices
#' estimated. Should be set to specific population names, or to \code{"all"} if
#' all populations should have matrices estimated.
#' @param patch A variable designating which patches or subpopulations will have
#' matrices estimated. Should be set to specific patch names, or to \code{"all"}
#' if matrices should be estimated for all patches. Defaults to \code{NA}, in
#' which case patch designations are ignored..
#' @param censor If \code{TRUE}, then data will be removed according to the
#' variable set in \code{censorcol}, such that only data with censor values
#' equal to \code{censorkeep} will remain. Defaults to \code{FALSE}.
#' @param stages An optional vector denoting the names of the variables within
#' the main vertical dataset coding for the stages of each individual in
#' occasions \emph{t}+1, \emph{t}, and \emph{t}-1. The names of stages in these
#' variables should match those used in the \code{stageframe} exactly. If left
#' blank, then \code{rlefko3()} will attempt to infer stages by matching values
#' of \code{alive}, \code{size}, \code{repst}, and \code{matst} to
#' characteristics noted in the associated \code{stageframe}.
#' @param alive A vector of names of binomial variables corresponding to status
#' as alive (\code{1}) or dead (\code{0}) in occasions \emph{t}+1, \emph{t}, and
#' \emph{t}-1, respectively.
#' @param obsst A vector of names of binomial variables corresponding to
#' observation status in occasions \emph{t}+1, \emph{t}, and \emph{t}-1,
#' respectively. Defaults to \code{NULL}, in which case observation status is
#' not used.
#' @param size A vector of names of variables coding the primary size variable
#' in occasions \emph{t}+1, \emph{t}, and \emph{t}-1, respectively. Defaults to 
#' \code{c("sizea3", "sizea2", "sizea1")}.
#' @param sizeb A vector of names of variables coding the secondary size
#' variable in occasions \emph{t}+1, \emph{t}, and \emph{t}-1, respectively.
#' Defaults to \code{NULL}, in which case this variable is not used.
#' @param sizec A vector of names of variables coding the tertiary size
#' variable in occasions \emph{t}+1, \emph{t}, and \emph{t}-1, respectively.
#' Defaults to \code{NULL}, in which case this variable is not used.
#' @param repst A vector of names of variables coding reproductive status in
#' occasions \emph{t}+1, \emph{t}, and \emph{t}-1, respectively. Defaults to 
#' \code{c("repstatus3", "repstatus2", "repstatus1")}. Must be supplied if
#' \code{stages} is not provided.
#' @param matst A vector of names of variables coding maturity status in
#' occasions \emph{t}+1, \emph{t}, and \emph{t}-1, respectively. Defaults to
#' \code{c("matstatus3", "matstatus2", "matstatus1")}. Must be supplied if
#' \code{stages} is not provided.
#' @param fec A vector of names of variables coding fecundity in occasions
#' \emph{t}+1, \emph{t}, and \emph{t}-1, respectively. Defaults to
#' \code{c("feca3", "feca2", "feca1")}.
#' @param supplement An optional data frame of class \code{lefkoSD} that
#' provides supplemental data that should be incorporated into the MPM. Three
#' kinds of data may be integrated this way: transitions to be estimated via the
#' use of proxy transitions, transition overwrites from the literature or
#' supplemental studies, and transition multipliers for fecundity. This data
#' frame should be produced using the \code{\link{supplemental}()} function.
#' Should be used in place of or in addition to an overwrite table (see 
#' \code{overwrite} below) and a reproduction matrix (see \code{repmatrix}
#' below).
#' @param repmatrix An optional reproduction matrix. This matrix is composed
#' mostly of 0s, with non-zero entries acting as element identifiers and
#' multipliers for fecundity (with 1 equaling full fecundity). If left blank,
#' and no \code{supplement} is provided, then \code{rlefko3()} will assume that
#' all stages marked as reproductive produce offspring at 1x that of estimated
#' fecundity, and that offspring production will yield the first stage noted as
#' propagule or immature. To prevent this behavior, input just \code{0}, which
#' will result in fecundity being estimated only for transitions noted in
#' \code{supplement} above. May be the dimensions of either a historical or an
#' ahistorical matrix. If the former, then the fecundity estimation of this
#' function may be unpredictable. If the latter, then all stages will be used in
#' occasion \emph{t}-1 for each suggested ahistorical transition.
#' @param overwrite An optional data frame developed with the
#' \code{\link{overwrite}()} function describing transitions to be overwritten
#' either with given values or with other estimated transitions. Note that this
#' function supplements overwrite data provided in \code{supplement}.
#' @param yearcol The variable name or column number corresponding to occasion
#' \emph{t} in the dataset.
#' @param popcol The variable name or column number corresponding to the
#' identity of the population.
#' @param patchcol The variable name or column number corresponding to patch in 
#' the dataset.
#' @param indivcol The variable name or column number coding individual
#' identity.
#' @param censorcol The variable name or column number denoting the censor
#' status. Only needed if \code{censor = TRUE}.
#' @param censorkeep The value of the censor variable denoting data elements to
#' keep. Defaults to \code{0}.
#' @param NRasRep If \code{data} does not include stage assignments, then this
#' option determines whether non-reproductive and reproductive individuals
#' should be lumped into the same stages. Defaults to \code{FALSE}.
#' @param format A string indicating whether to estimate matrices in
#' \code{ehrlen} format or \code{deVries} format. The latter adds one unborn
#' prior stage to account for the prior state of newborns. Defaults to
#' \code{ehrlen} format.
#' @param reduce A logical value denoting whether to remove historical stages
#' associated exclusively with zero transitions. These are removed only if the
#' respective row and column sums in ALL matrices estimated equal 0. Defaults to
#' \code{FALSE}.
#' @param simple A logical value indicating whether to produce \code{A},
#' \code{U}, and \code{F} matrices, or only the latter two. Defaults to
#' \code{FALSE}, in which case all three are output.
#' @param err_check A logical value indicating whether to append extra
#' information used in matrix calculation within the output list. Defaults to
#' \code{FALSE}.
#' @param sparse_output A logical value indicating whether to output matrices
#' in sparse format. Defaults to \code{FALSE}, in which case all matrices are
#' output in standard matrix format.
#'
#' @return If all inputs are properly formatted, then this function will return
#' an object of class \code{lefkoMat}, which is a list that holds the matrix
#' projection model and all of its metadata. Its structure is a list with the
#' following elements:
#'
#' \item{A}{A list of full projection matrices in order of sorted populations,
#' patches, and occasions. All matrices output in the \code{matrix} class, or in
#' the \code{dgCMatrix} class from the \code{Matrix} package if sparse.}
#' \item{U}{A list of survival transition matrices sorted as in \code{A}. All 
#' matrices output in the \code{matrix} class, or in the \code{dgCMatrix} class
#' from the \code{Matrix} package if sparse.}
#' \item{F}{A list of fecundity matrices sorted as in \code{A}. All matrices 
#' output in the \code{matrix} class, or in the \code{dgCMatrix} class from the
#' \code{Matrix} package if sparse.}
#' \item{hstages}{A data frame matrix showing the pairing of ahistorical stages
#' used to create historical stage pairs.}
#' \item{agestages}{A data frame showing age-stage pairs. In this function, it
#' is set to NA. Only used in output to function \code{aflefko2}().}
#' \item{ahstages}{A data frame detailing the characteristics of associated
#' ahistorical stages, in the form of a modified stageframe that includes
#' status as an entry stage through reproduction.}
#' \item{labels}{A data frame giving the population, patch, and year of each 
#' matrix in order.}
#' \item{dataqc}{A vector showing the numbers of individuals and rows in the
#' vertical dataset used as input.}
#' \item{matrixqc}{A short vector describing the number of non-zero elements in
#' \code{U} and \code{F} matrices, and the number of annual matrices.}
#' \item{modelqc}{This is the \code{qc} portion of the \code{modelsuite} input
#' in function-based MPMs. Empty in this function.}
#'
#' @section Notes:
#' The default behavior of this function is to estimate fecundity with regards
#' to transitions specified via associated fecundity multipliers in either
#' \code{supplement} or \code{repmatrix}. If both of these fields are left
#' empty, then fecundity will be estimated at full for all transitions leading
#' from reproductive stages to immature and propagule stages. However, if a
#' \code{supplement} is provided and a \code{repmatrix} is not, or if
#' \code{repmatrix} is set to 0, then only fecundity transitions noted in the
#' supplement will be set to non-zero values. To use the default behavior of
#' setting all reproductive stages to reproduce at full fecundity into immature
#' and propagule stages but incorporate given or proxy survival transitions,
#' input those given and proxy transitions through the \code{overwrite} option.
#' 
#' The reproduction matrix (field \code{repmatrix}) may be supplied as either
#' historical or ahistorical. If provided as ahistorical, then \code{flefko3()}
#' will assume that all historical transitions involving stages noted for
#' occasions \emph{t} and \emph{t}+1 should be set to the respective fecundity
#' multipliers noted.
#' 
#' Users may at times wish to estimate MPMs using a dataset incorporating
#' multiple patches or subpopulations. Should the aim of analysis be a general
#' MPM that does not distinguish these patches or subpopulations, the
#' \code{patchcol} variable should be left to \code{NA}, which is the default.
#' Otherwise the variable identifying patch needs to be named.
#'
#' Input options including multiple variable names must be entered in the order
#' of variables in occasion \emph{t}+1, \emph{t}, and \emph{t}-1. Rearranging
#' the order WILL lead to erroneous calculations, and may lead to
#' fatal errors.
#'
#' Although this function is capable of assigning stages given an input
#' stageframe, it lacks the power of \code{\link{verticalize3}()} and
#' \code{\link{historicalize3}()} in this regard. Users are strongly
#' encouraged to use the latter two functions for stage assignment.
#' 
#' @seealso \code{\link{mpm_create}()}
#' @seealso \code{\link{flefko3}()}
#' @seealso \code{\link{flefko2}()}
#' @seealso \code{\link{aflefko2}()}
#' @seealso \code{\link{arlefko2}()}
#' @seealso \code{\link{fleslie}()}
#' @seealso \code{\link{rlefko2}()}
#' @seealso \code{\link{rleslie}()}
#' 
#' @examples
#' # Lathyrus example
#' data(lathyrus)
#' 
#' sizevector <- c(0, 100, 13, 127, 3730, 3800, 0)
#' stagevector <- c("Sd", "Sdl", "VSm", "Sm", "VLa", "Flo", "Dorm")
#' repvector <- c(0, 0, 0, 0, 0, 1, 0)
#' obsvector <- c(0, 1, 1, 1, 1, 1, 0)
#' matvector <- c(0, 0, 1, 1, 1, 1, 1)
#' immvector <- c(1, 1, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0)
#' indataset <- c(0, 1, 1, 1, 1, 1, 1)
#' binvec <- c(0, 100, 11, 103, 3500, 3800, 0.5)
#' 
#' lathframe <- sf_create(sizes = sizevector, stagenames = stagevector, 
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector, 
#'   immstatus = immvector, indataset = indataset, binhalfwidth = binvec, 
#'   propstatus = propvector)
#' 
#' lathvert <- verticalize3(lathyrus, noyears = 4, firstyear = 1988, 
#'   patchidcol = "SUBPLOT", individcol = "GENET", blocksize = 9, 
#'   juvcol = "Seedling1988", sizeacol = "Volume88", repstracol = "FCODE88", 
#'   fecacol = "Intactseed88", deadacol = "Dead1988", nonobsacol = "Dormant1988", 
#'   stageassign = lathframe, stagesize = "sizea", censorcol = "Missing1988", 
#'   censorkeep = NA, censor = TRUE)
#' 
#' lathsupp3 <- supplemental(stage3 = c("Sd", "Sd", "Sdl", "Sdl", "Sd", "Sdl", "mat"),
#'   stage2 = c("Sd", "Sd", "Sd", "Sd", "rep", "rep", "Sdl"),
#'   stage1 = c("Sd", "rep", "Sd", "rep", "npr", "npr", "Sd"),
#'   eststage3 = c(NA, NA, NA, NA, NA, NA, "mat"),
#'   eststage2 = c(NA, NA, NA, NA, NA, NA, "Sdl"),
#'   eststage1 = c(NA, NA, NA, NA, NA, NA, "NotAlive"),
#'   givenrate = c(0.345, 0.345, 0.054, 0.054, NA, NA, NA),
#'   multiplier = c(NA, NA, NA, NA, 0.345, 0.054, NA),
#'   type = c(1, 1, 1, 1, 3, 3, 1), type_t12 = c(1, 2, 1, 2, 1, 1, 1),
#'   stageframe = lathframe, historical = TRUE)
#' 
#' ehrlen3 <- rlefko3(data = lathvert, stageframe = lathframe, year = "all", 
#'   stages = c("stage3", "stage2", "stage1"), supplement = lathsupp3,
#'   yearcol = "year2", indivcol = "individ")
#' 
#' # Cypripedium example
#' data(cypdata)
#' 
#' sizevector <- c(0, 0, 0, 0, 0, 0, 1, 2.5, 4.5, 8, 17.5)
#' stagevector <- c("SD", "P1", "P2", "P3", "SL", "D", "XSm", "Sm", "Md", "Lg",
#'   "XLg")
#' repvector <- c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
#' obsvector <- c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
#' matvector <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
#' immvector <- c(0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#' indataset <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
#' binvec <- c(0, 0, 0, 0, 0, 0.5, 0.5, 1, 1, 2.5, 7)
#' 
#' cypframe_raw <- sf_create(sizes = sizevector, stagenames = stagevector,
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector,
#'   propstatus = propvector, immstatus = immvector, indataset = indataset,
#'   binhalfwidth = binvec)
#' 
#' cypraw_v1 <- verticalize3(data = cypdata, noyears = 6, firstyear = 2004,
#'   patchidcol = "patch", individcol = "plantid", blocksize = 4,
#'   sizeacol = "Inf2.04", sizebcol = "Inf.04", sizeccol = "Veg.04",
#'   repstracol = "Inf.04", repstrbcol = "Inf2.04", fecacol = "Pod.04",
#'   stageassign = cypframe_raw, stagesize = "sizeadded", NAas0 = TRUE,
#'   NRasRep = TRUE)
#' 
#' cypsupp3r <- supplemental(stage3 = c("SD", "SD", "P1", "P1", "P2", "P3", "SL",
#'     "D", "XSm", "Sm", "D", "XSm", "Sm", "mat", "mat", "mat", "SD", "P1"),
#'   stage2 = c("SD", "SD", "SD", "SD", "P1", "P2", "P3", "SL", "SL", "SL", "SL",
#'     "SL", "SL", "D", "XSm", "Sm", "rep", "rep"),
#'   stage1 = c("SD", "rep", "SD", "rep", "SD", "P1", "P2", "P3", "P3", "P3",
#'     "SL", "SL", "SL", "SL", "SL", "SL", "mat", "mat"),
#'   eststage3 = c(NA, NA, NA, NA, NA, NA, NA, "D", "XSm", "Sm", "D", "XSm", "Sm",
#'     "mat", "mat", "mat", NA, NA),
#'   eststage2 = c(NA, NA, NA, NA, NA, NA, NA, "XSm", "XSm", "XSm", "XSm", "XSm",
#'     "XSm", "D", "XSm", "Sm", NA, NA),
#'   eststage1 = c(NA, NA, NA, NA, NA, NA, NA, "XSm", "XSm", "XSm", "XSm", "XSm",
#'     "XSm", "XSm", "XSm", "XSm", NA, NA),
#'   givenrate = c(0.1, 0.1, 0.2, 0.2, 0.2, 0.2, 0.25, NA, NA, NA, NA, NA, NA,
#'     NA, NA, NA, NA, NA),
#'   multiplier = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
#'     NA, 0.5, 0.5),
#'   type = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3),
#'   type_t12 = c(1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
#'   stageframe = cypframe_raw, historical = TRUE)
#' 
#' cypmatrix3r <- rlefko3(data = cypraw_v1, stageframe = cypframe_raw,
#'   year = "all", patch = "all", stages = c("stage3", "stage2", "stage1"),
#'   size = c("size3added", "size2added", "size1added"),
#'   supplement = cypsupp3r, yearcol = "year2", patchcol = "patchid",
#'   indivcol = "individ")
#' 
#' @export
rlefko3 <- function(data, stageframe, year = "all", pop = NULL, patch = NULL,
  censor = FALSE, stages = NULL, alive = c("alive3", "alive2", "alive1"),
  obsst = NULL, size = c("sizea3", "sizea2", "sizea1"), sizeb = NULL,
  sizec = NULL, repst = c("repstatus3", "repstatus2", "repstatus1"),
  matst = c("matstatus3", "matstatus2", "matstatus1"),
  fec = c("feca3", "feca2", "feca1"), supplement = NULL, repmatrix = NULL,
  overwrite = NULL, yearcol = NULL, popcol = NULL, patchcol = NULL, indivcol = NULL,
  censorcol = NULL, censorkeep = 0, NRasRep = FALSE, format = "ehrlen",
  reduce = FALSE, simple = FALSE, err_check = FALSE, sparse_output = FALSE) {
  
  format_dev <- FALSE
  
  if (grepl("dev", tolower(format))) {
    format_dev <- TRUE
  }
  
  output <- mpm_create(historical = TRUE, stage = TRUE, age = FALSE,
    devries = format_dev, reduce = reduce, data = data, year = year, pop = pop,
    patch = patch, stageframe = stageframe, supplement = supplement, 
    overwrite = overwrite, repmatrix = repmatrix, alive = alive,
    obsst = obsst, size = size, sizeb = sizeb, sizec = sizec, repst = repst,
    matst = matst, fec = fec, stages = stages, yearcol = yearcol,
    popcol = popcol, patchcol = patchcol, indivcol = indivcol,
    censorcol = censorcol, censor = censor, censorkeep = censorkeep,
    stage_NRasRep = NRasRep, simple = simple, err_check = err_check,
    sparse_output = sparse_output)
  
  return(output)
}

#' Create Raw Ahistorical Matrix Projection Model
#'
#' Function \code{rlefko2()} returns raw ahistorical MPMs, including the
#' associated component transition and fecundity matrices, a data frame
#' describing the ahistorical stages used, and a data frame describing the
#' population, patch, and occasion time associated with each matrix.
#' 
#' @name rlefko2
#' 
#' @param data  A vertical demographic data frame, with variables corresponding 
#' to the naming conventions in \code{\link{verticalize3}()} and
#' \code{\link{historicalize3}()}.
#' @param stageframe A stageframe object that includes information on the size,
#' observation status, propagule status, reproduction status, immaturity status,
#' and maturity status of each ahistorical stage.
#' @param year A variable corresponding to observation occasion, or a set
#' of such values, given in values associated with the \code{year} term used in
#' vital rate model development. Can also equal \code{"all"}, in which case
#' matrices will be estimated for all occasion times. Defaults to \code{"all"}.
#' @param pop A variable designating which populations will have matrices
#' estimated. Should be set to specific population names, or to \code{"all"} if
#' all populations should have matrices estimated.
#' @param patch A variable designating which patches or subpopulations will have
#' matrices estimated. Should be set to specific patch names, or to \code{"all"}
#' if matrices should be estimated for all patches. Defaults to \code{NA}, in
#' which case patch designations are ignored..
#' @param censor If \code{TRUE}, then data will be removed according to the
#' variable set in \code{censorcol}, such that only data with censor values
#' equal to \code{censorkeep} will remain. Defaults to \code{FALSE}.
#' @param stages An optional vector denoting the names of the variables within
#' the main vertical dataset coding for the stages of each individual in
#' occasions \emph{t}+1 and \emph{t}. The names of stages in these variables
#' should match those used in the \code{stageframe} exactly. If left blank, then
#' \code{rlefko2()} will attempt to infer stages by matching values of
#' \code{alive}, \code{size}, \code{repst}, and \code{matst} to characteristics
#' noted in the associated \code{stageframe}.
#' @param alive A vector of names of binomial variables corresponding to status
#' as alive (\code{1}) or dead (\code{0}) in occasions \emph{t}+1 and \emph{t},
#' respectively.
#' @param obsst A vector of names of binomial variables corresponding to
#' observation status in occasions \emph{t}+1, \emph{t}, and \emph{t}-1,
#' respectively. Defaults to \code{NULL}, in which case observation status is
#' not used.
#' @param size A vector of names of variables coding the primary size variable
#' in occasions \emph{t}+1 and \emph{t}, respectively. Defaults to
#' \code{c("sizea3", "sizea2")}.
#' @param sizeb A vector of names of variables coding the secondary size
#' variable in occasions \emph{t}+1 and \emph{t}, respectively. Defaults to
#' \code{NULL}, in which case this variable is not used.
#' @param sizec A vector of names of variables coding the tertiary size
#' variable in occasions \emph{t}+1 and \emph{t}, respectively. Defaults to
#' \code{NULL}, in which case this variable is not used.
#' @param repst A vector of names of variables coding reproductive status in
#' occasions \emph{t}+1 and \emph{t}, respectively. Defaults to 
#' \code{c("repstatus3", "repstatus2")}. Must be supplied if \code{stages} is
#' not provided.
#' @param matst A vector of names of variables coding maturity status in
#' occasions \emph{t}+1 and \emph{t}, respectively. Defaults to
#' \code{c("matstatus3", "matstatus2")}. Must be supplied if \code{stages} is
#' not provided.
#' @param fec A vector of names of variables coding fecundity in occasions
#' \emph{t}+1 and \emph{t}, respectively. Defaults to \code{c("feca3", "feca2")}.
#' @param supplement An optional data frame of class \code{lefkoSD} that
#' provides supplemental data that should be incorporated into the MPM. Three
#' kinds of data may be integrated this way: transitions to be estimated via the
#' use of proxy transitions, transition overwrites from the literature or
#' supplemental studies, and transition multipliers for fecundity. This data
#' frame should be produced using the \code{\link{supplemental}()} function.
#' Should be used in place of or in addition to an overwrite table (see 
#' \code{overwrite} below) and a reproduction matrix (see \code{repmatrix}
#' below).
#' @param repmatrix An optional reproduction matrix. This matrix is composed
#' mostly of 0s, with non-zero entries acting as element identifiers and
#' multipliers for fecundity (with 1 equaling full fecundity). If left blank,
#' and no \code{supplement} is provided, then \code{rlefko2()} will assume that
#' all stages marked as reproductive produce offspring at 1x that of estimated
#' fecundity, and that offspring production will yield the first stage noted as
#' propagule or immature. To prevent this behavior, input just \code{0}, which
#' will result in fecundity being estimated only for transitions noted in
#' \code{supplement} above. Must be the dimensions of an ahistorical matrix.
#' @param overwrite An optional data frame developed with the
#' \code{\link{overwrite}()} function describing transitions to be overwritten
#' either with given values or with other estimated transitions. Note that this
#' function supplements overwrite data provided in \code{supplement}.
#' @param yearcol The variable name or column number corresponding to occasion 
#' \emph{t} in the dataset.
#' @param popcol The variable name or column number corresponding to the
#' identity of the population.
#' @param patchcol The variable name or column number corresponding to patch in
#' the dataset.
#' @param indivcol The variable name or column number coding individual
#' identity.
#' @param censorcol The variable name or column number denoting the censor
#' status. Only needed if \code{censor = TRUE}.
#' @param censorkeep The value of the censor variable denoting data elements to
#' keep. Defaults to \code{0}.
#' @param NRasRep If \code{data} does not include stage assignments, then this
#' option determines whether non-reproductive and reproductive individuals
#' should be lumped into the same stages. Defaults to \code{FALSE}.
#' @param reduce A logical value denoting whether to remove ahistorical stages
#' associated with only zero transitions. These are removed only if the
#' respective row and column sums in ALL matrices estimated equal 0. Defaults to
#' \code{FALSE}.
#' @param simple A logical value indicating whether to produce \code{A},
#' \code{U}, and \code{F} matrices, or only the latter two. Defaults to
#' \code{FALSE}, in which case all three are output.
#' @param err_check A logical value indicating whether to append extra
#' information used in matrix calculation within the output list. Defaults to
#' \code{FALSE}.
#' @param sparse_output A logical value indicating whether to output matrices
#' in sparse format. Defaults to \code{FALSE}, in which case all matrices are
#' output in standard matrix format.
#' 
#' @return If all inputs are properly formatted, then this function will return
#' an object of class \code{lefkoMat}, which is a list that holds the matrix
#' projection model and all of its metadata. Its structure is a list with the
#' following elements:
#' 
#' \item{A}{A list of full projection matrices in order of sorted populations,
#' patches, and occasions. All matrices output in the \code{matrix} class, or in
#' the \code{dgCMatrix} class from the \code{Matrix} package if sparse.}
#' \item{U}{A list of survival transition matrices sorted as in \code{A}. All 
#' matrices output in the \code{matrix} class, or in the \code{dgCMatrix} class
#' from the \code{Matrix} package if sparse.}
#' \item{F}{A list of fecundity matrices sorted as in \code{A}. All matrices 
#' output in the \code{matrix} class, or in the \code{dgCMatrix} class from the
#' \code{Matrix} package if sparse.}
#' \item{hstages}{A data frame matrix showing the pairing of ahistorical stages
#' used to create historical stage pairs. Set to NA for ahistorical matrices.}
#' \item{agestages}{A data frame showing age-stage pairs. In this function, it
#' is set to NA. Only used in output to function \code{aflefko2}().}
#' \item{ahstages}{A data frame detailing the characteristics of associated
#' ahistorical stages, in the form of a modified stageframe that includes
#' status as an entry stage through reproduction.}
#' \item{labels}{A data frame giving the population, patch, and year of each 
#' matrix in order.}
#' \item{dataqc}{A vector showing the numbers of individuals and rows in the
#' vertical dataset used as input.}
#' \item{matrixqc}{A short vector describing the number of non-zero elements in
#' \code{U} and \code{F} matrices, and the number of annual matrices.}
#' \item{modelqc}{This is the \code{qc} portion of the \code{modelsuite} input
#' in function-based MPMs. Empty in this function.}
#'
#' @section Notes:
#' The default behavior of this function is to estimate fecundity with regards
#' to transitions specified via associated fecundity multipliers in either
#' \code{supplement} or \code{repmatrix}. If both of these fields are left
#' empty, then fecundity will be estimated at full for all transitions leading
#' from reproductive stages to immature and propagule stages. However, if a
#' \code{supplement} is provided and a \code{repmatrix} is not, or if
#' \code{repmatrix} is set to 0, then only fecundity transitions noted in the
#' supplement will be set to non-zero values. To use the default behavior of
#' setting all reproductive stages to reproduce at full fecundity into immature
#' and propagule stages but also incorporate given or proxy survival
#' transitions, input those given and proxy transitions through the
#' \code{overwrite} options.
#' 
#' The reproduction matrix (field \code{repmatrix}) may only be supplied as
#' ahistorical. If provided as historical, then \code{rlefko2()} will fail and
#' produce an error.
#' 
#' Users may at times wish to estimate MPMs using a dataset incorporating
#' multiple patches or subpopulations. Should the aim of analysis be a general
#' MPM that does not distinguish these patches or subpopulations, the
#' \code{patchcol} variable should be left to \code{NA}, which is the default.
#' Otherwise the variable identifying patch needs to be named.
#'
#' Input options including multiple variable names must be entered in the order
#' of variables in occasion \emph{t}+1 and \emph{t}. Rearranging the order WILL
#' lead to erroneous calculations, and may lead to fatal errors.
#' 
#' Although this function is capable of assigning stages given an input
#' stageframe, it lacks the power of \code{\link{verticalize3}()} and
#' \code{\link{historicalize3}()} in this regard. Users are strongly
#' encouraged to use the latter two functions for stage assignment.
#' 
#' @seealso \code{\link{mpm_create}()}
#' @seealso \code{\link{flefko3}()}
#' @seealso \code{\link{flefko2}()}
#' @seealso \code{\link{aflefko2}()}
#' @seealso \code{\link{arlefko2}()}
#' @seealso \code{\link{fleslie}()}
#' @seealso \code{\link{rlefko3}()}
#' @seealso \code{\link{rleslie}()}
#' 
#' @examples
#' # Lathyrus example
#' data(lathyrus)
#' 
#' sizevector <- c(0, 100, 13, 127, 3730, 3800, 0)
#' stagevector <- c("Sd", "Sdl", "VSm", "Sm", "VLa", "Flo", "Dorm")
#' repvector <- c(0, 0, 0, 0, 0, 1, 0)
#' obsvector <- c(0, 1, 1, 1, 1, 1, 0)
#' matvector <- c(0, 0, 1, 1, 1, 1, 1)
#' immvector <- c(1, 1, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0)
#' indataset <- c(0, 1, 1, 1, 1, 1, 1)
#' binvec <- c(0, 100, 11, 103, 3500, 3800, 0.5)
#' 
#' lathframe <- sf_create(sizes = sizevector, stagenames = stagevector, 
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector, 
#'   immstatus = immvector, indataset = indataset, binhalfwidth = binvec, 
#'   propstatus = propvector)
#' 
#' lathvert <- verticalize3(lathyrus, noyears = 4, firstyear = 1988, 
#'   patchidcol = "SUBPLOT", individcol = "GENET", blocksize = 9, 
#'   juvcol = "Seedling1988", sizeacol = "Volume88", repstracol = "FCODE88", 
#'   fecacol = "Intactseed88", deadacol = "Dead1988", nonobsacol = "Dormant1988", 
#'   stageassign = lathframe, stagesize = "sizea", censorcol = "Missing1988", 
#'   censorkeep = NA, censor = TRUE)
#' 
#' lathsupp2 <- supplemental(stage3 = c("Sd", "Sdl", "Sd", "Sdl"), 
#'   stage2 = c("Sd", "Sd", "rep", "rep"),
#'   givenrate = c(0.345, 0.054, NA, NA),
#'   multiplier = c(NA, NA, 0.345, 0.054),
#'   type = c(1, 1, 3, 3), stageframe = lathframe, historical = FALSE)
#' 
#' ehrlen2 <- rlefko2(data = lathvert, stageframe = lathframe, year = "all", 
#'   stages = c("stage3", "stage2"), supplement = lathsupp2, yearcol = "year2",
#'   indivcol = "individ")
#' 
#' # Cypripedium example
#' data(cypdata)
#' 
#' sizevector <- c(0, 0, 0, 0, 0, 0, 1, 2.5, 4.5, 8, 17.5)
#' stagevector <- c("SD", "P1", "P2", "P3", "SL", "D", "XSm", "Sm", "Md", "Lg",
#'   "XLg")
#' repvector <- c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
#' obsvector <- c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
#' matvector <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
#' immvector <- c(0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#' indataset <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
#' binvec <- c(0, 0, 0, 0, 0, 0.5, 0.5, 1, 1, 2.5, 7)
#' 
#' cypframe_raw <- sf_create(sizes = sizevector, stagenames = stagevector,
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector,
#'   propstatus = propvector, immstatus = immvector, indataset = indataset,
#'   binhalfwidth = binvec)
#' 
#' cypraw_v1 <- verticalize3(data = cypdata, noyears = 6, firstyear = 2004,
#'   patchidcol = "patch", individcol = "plantid", blocksize = 4,
#'   sizeacol = "Inf2.04", sizebcol = "Inf.04", sizeccol = "Veg.04",
#'   repstracol = "Inf.04", repstrbcol = "Inf2.04", fecacol = "Pod.04",
#'   stageassign = cypframe_raw, stagesize = "sizeadded", NAas0 = TRUE,
#'   NRasRep = TRUE)
#' 
#' # Here we use supplemental() to provide overwrite and reproductive info
#' cypsupp2r <- supplemental(stage3 = c("SD", "P1", "P2", "P3", "SL", "D", 
#'     "XSm", "Sm", "SD", "P1"),
#'   stage2 = c("SD", "SD", "P1", "P2", "P3", "SL", "SL", "SL", "rep",
#'     "rep"),
#'   eststage3 = c(NA, NA, NA, NA, NA, "D", "XSm", "Sm", NA, NA),
#'   eststage2 = c(NA, NA, NA, NA, NA, "XSm", "XSm", "XSm", NA, NA),
#'   givenrate = c(0.10, 0.20, 0.20, 0.20, 0.25, NA, NA, NA, NA, NA),
#'   multiplier = c(NA, NA, NA, NA, NA, NA, NA, NA, 0.5, 0.5),
#'   type =c(1, 1, 1, 1, 1, 1, 1, 1, 3, 3),
#'   stageframe = cypframe_raw, historical = FALSE)
#' 
#' cypmatrix2r <- rlefko2(data = cypraw_v1, stageframe = cypframe_raw, 
#'   year = "all", patch = "all", stages = c("stage3", "stage2", "stage1"),
#'   size = c("size3added", "size2added"), supplement = cypsupp2r,
#'   yearcol = "year2", patchcol = "patchid", indivcol = "individ")
#' 
#' @export
rlefko2 <- function(data, stageframe, year = "all", pop = NULL, patch = NULL,
  censor = FALSE, stages = NULL, alive = c("alive3", "alive2"),
  obsst = NULL, size = c("sizea3", "sizea2"), sizeb = NULL, sizec = NULL,
  repst = c("repstatus3", "repstatus2"), matst = c("matstatus3", "matstatus2"),
  fec = c("feca3", "feca2"), supplement = NULL, repmatrix = NULL,
  overwrite = NULL, yearcol = NULL, popcol = NULL, patchcol = NULL, indivcol = NULL,
  censorcol = NULL, censorkeep = 0, NRasRep = FALSE, reduce = FALSE, simple = FALSE,
  err_check = FALSE, sparse_output = FALSE) {

  output <- mpm_create(historical = FALSE, stage = TRUE, age = FALSE,
    devries = FALSE, reduce = reduce, data = data, year = year, pop = pop,
    patch = patch, stageframe = stageframe, supplement = supplement, 
    overwrite = overwrite, repmatrix = repmatrix, alive = alive,
    obsst = obsst, size = size, sizeb = sizeb, sizec = sizec, repst = repst,
    matst = matst, fec = fec, stages = stages, yearcol = yearcol,
    popcol = popcol, patchcol = patchcol, indivcol = indivcol,
    censorcol = censorcol, censor = censor, censorkeep = censorkeep,
    stage_NRasRep = NRasRep, simple = simple, err_check = err_check,
    sparse_output = sparse_output)
  
  return(output)
}

#' Create Raw Ahistorical Age x Stage Matrix Projection Model
#'
#' Function \code{arlefko2()} returns raw ahistorical age x stage MPMs
#' corresponding to the patches and occasion times given, including the
#' associated component transition and fecundity matrices, data frames detailing
#' the characteristics of ahistorical stages and the exact age-stage
#' combinations corresponding to rows and columns in estimated matrices, and a
#' data frame characterizing the patch and occasion time combinations
#' corresponding to these matrices.
#' 
#' @name arlefko2
#' 
#' @param data  A vertical demographic data frame, with variables corresponding 
#' to the naming conventions in \code{\link{verticalize3}()} and
#' \code{\link{historicalize3}()}.
#' @param stageframe A stageframe object that includes information on the size,
#' observation status, propagule status, reproduction status, immaturity status,
#' and maturity status of each ahistorical stage. Should also incorporate bin
#' widths if size is continuous.
#' @param year A variable corresponding to observation occasion, or a set
#' of such values, given in values associated with the year term used in linear 
#' model development. Defaults to \code{"all"}, in which case matrices will be
#' estimated for all occasions.
#' @param pop A variable designating which populations will have matrices
#' estimated. Should be set to specific population names, or to \code{"all"} if
#' all populations should have matrices estimated.
#' @param patch A variable designating which patches or subpopulations will have
#' matrices estimated. Should be set to specific patch names, or to \code{"all"}
#' if matrices should be estimated for all patches. Defaults to \code{NA}, in
#' which case patch designations are ignored.
#' @param censor If \code{TRUE}, then data will be removed according to the
#' variable set in \code{censorcol}, such that only data with censor values
#' equal to \code{censorkeep} will remain. Defaults to \code{FALSE}.
#' @param stages An optional vector denoting the names of the variables within
#' the main vertical dataset coding for the stages of each individual in
#' occasions \emph{t}+1 and \emph{t}. The names of stages in these variables
#' should match those used in the \code{stageframe} exactly. If left blank, then
#' \code{arlefko2()} will attempt to infer stages by matching values of
#' \code{alive}, \code{size}, \code{repst}, and \code{matst} to characteristics
#' noted in the associated \code{stageframe}.
#' @param alive A vector of names of binomial variables corresponding to status
#' as alive (\code{1}) or dead (\code{0}) in occasions \emph{t}+1 ans \emph{t},
#' respectively.
#' @param obsst A vector of names of binomial variables corresponding to
#' observation status in occasions \emph{t}+1, \emph{t}, and \emph{t}-1,
#' respectively. Defaults to \code{NULL}, in which case observation status is
#' not used.
#' @param size A vector of names of variables coding the primary size variable
#' in occasions \emph{t}+1 and \emph{t}, respectively. Defaults to
#' \code{c("sizea3", "sizea2")}.
#' @param sizeb A vector of names of variables coding the secondary size
#' variable in occasions \emph{t}+1 and \emph{t}, respectively. Defaults to
#' \code{NULL}, in which case this variable is not used.
#' @param sizec A vector of names of variables coding the tertiary size
#' variable in occasions \emph{t}+1 and \emph{t}, respectively. Defaults to
#' \code{NULL}, in which case this variable is not used.
#' @param repst A vector of names of variables coding reproductive status in
#' occasions \emph{t}+1 and \emph{t}, respectively. Defaults to 
#' \code{c("repstatus3", "repstatus2")}. Must be supplied if \code{stages} is
#' not provided.
#' @param matst A vector of names of variables coding maturity status in
#' occasions \emph{t}+1 and \emph{t}, respectively. Defaults to
#' \code{c("matstatus3", "matstatus2")}. Must be supplied if \code{stages} is
#' not provided.
#' @param fec A vector of names of variables coding fecundity in occasions
#' \emph{t}+1 and \emph{t}, respectively. Defaults to \code{c("feca3", "feca2")}.
#' @param supplement An optional data frame of class \code{lefkoSD} that
#' provides supplemental data that should be incorporated into the MPM. Three
#' kinds of data may be integrated this way: transitions to be estimated via the
#' use of proxy transitions, transition overwrites from the literature or
#' supplemental studies, and transition multipliers for survival and fecundity.
#' This data frame should be produced using the \code{\link{supplemental}()}
#' function. Can be used in place of or in addition to an overwrite table (see 
#' \code{overwrite} below) and a reproduction matrix (see \code{repmatrix}
#' below).
#' @param repmatrix An optional reproduction matrix. This matrix is composed
#' mostly of 0s, with non-zero entries acting as element identifiers and
#' multipliers for fecundity (with 1 equaling full fecundity). If left blank,
#' and no \code{supplement} is provided, then \code{aflefko2()} will assume that
#' all stages marked as reproductive produce offspring at 1x that of estimated
#' fecundity, and that offspring production will yield the first stage noted as
#' propagule or immature.  To prevent this behavior, input just \code{0}, which
#' will result in fecundity being estimated only for transitions noted in
#' \code{supplement} above. Must be the dimensions of an ahistorical stage-based
#' matrix.
#' @param overwrite An optional data frame developed with the
#' \code{\link{overwrite}()} function describing transitions to be overwritten
#' either with given values or with other estimated transitions. Note that this
#' function supplements overwrite data provided in \code{supplement}.
#' @param agecol The variable name or column corresponding to age in time
#' \emph{t}. Defaults to \code{"obsage"}.
#' @param yearcol The variable name or column number corresponding to occasion 
#' \emph{t} in the dataset.
#' @param popcol The variable name or column number corresponding to the
#' identity of the population.
#' @param patchcol The variable name or column number corresponding to patch in
#' the dataset.
#' @param indivcol The variable name or column number coding individual
#' identity.
#' @param agecol The variable name or column number coding for age in time
#' \emph{t}.
#' @param censorcol The variable name or column number denoting the censor
#' status. Only needed if \code{censor = TRUE}.
#' @param censorkeep The value of the censor variable denoting data elements to
#' keep. Defaults to \code{0}.
#' @param final_age The final age to model in the matrix. Defaults to the
#' maximum age in the dataset.
#' @param continue A logical value designating whether to allow continued
#' survival of individuals past the final age noted in the stageframe, using the 
#' demographic characteristics of the final age. Defaults to \code{TRUE}.
#' @param prebreeding A logical value indicating whether the life history model
#' is a pre-breeding model. Defaults to \code{TRUE}.
#' @param NRasRep If \code{data} does not include stage assignments, then this
#' option determines whether non-reproductive and reproductive individuals
#' should be lumped into the same stages. Defaults to \code{FALSE}.
#' @param reduce A logical value denoting whether to remove age-stages
#' associated with only zero transitions. These are removed only if the
#' respective row and column sums in ALL matrices estimated equal 0. Defaults to
#' \code{FALSE}.
#' @param simple A logical value indicating whether to produce \code{A},
#' \code{U}, and \code{F} matrices, or only the latter two. Defaults to
#' \code{FALSE}, in which case all three are output.
#' @param err_check A logical value indicating whether to append extra
#' information used in matrix calculation within the output list. Defaults to
#' \code{FALSE}.
#' @param sparse_output A logical value indicating whether to output matrices
#' in sparse format. Defaults to \code{FALSE}, in which case all matrices are
#' output in standard matrix format.
#' 
#' @return If all inputs are properly formatted, then this function will return
#' an object of class \code{lefkoMat}, which is a list that holds the matrix
#' projection model and all of its metadata. Its structure is a list with the
#' following elements:
#' 
#' \item{A}{A list of full projection matrices in order of sorted patches and
#' occasions. All matrices output in R's \code{matrix} class, or in the
#' \code{dgCMatrix} class from the \code{Matrix} package if sparse.}
#' \item{U}{A list of survival transition matrices sorted as in \code{A}. All 
#' matrices output in R's \code{matrix} class, or in the \code{dgCMatrix} class
#' from the \code{Matrix} package if sparse.}
#' \item{F}{A list of fecundity matrices sorted as in \code{A}. All matrices 
#' output in R's \code{matrix} class, or in the \code{dgCMatrix} class from the
#' \code{Matrix} package if sparse.}
#' \item{hstages}{A data frame matrix showing the pairing of ahistorical stages
#' used to create historical stage pairs. Set to \code{NA} for age-by-stage
#' MPMs.}
#' \item{agestages}{A data frame showing the stage number and stage name
#' corresponding to \code{ahstages}, as well as the associated age, of each
#' row in each age-by-stage matrix.}
#' \item{ahstages}{A data frame detailing the characteristics of associated
#' ahistorical stages, in the form of a modified stageframe that includes
#' status as an entry stage through reproduction.}
#' \item{labels}{A data frame giving the patch and year of each matrix in order.
#' In \code{aflefko2()}, only one population may be analyzed at once, and so
#' \code{pop = NA}}
#' \item{dataqc}{A vector showing the numbers of individuals and rows in the
#' vertical dataset used as input.}
#' \item{matrixqc}{A short vector describing the number of non-zero elements in
#' \code{U} and \code{F} matrices, and the number of annual matrices.}
#' \item{modelqc}{This is the \code{qc} portion of the \code{modelsuite} input
#' in function-based MPMs. Empty in this function.}
#' 
#' @section Notes:
#' The default behavior of this function is to estimate fecundity with regards
#' to transitions specified via associated fecundity multipliers in either
#' \code{supplement} or \code{repmatrix}. If both of these fields are left
#' empty, then fecundity will be estimated at full for all transitions leading
#' from reproductive stages to immature and propagule stages. However, if a
#' \code{supplement} is provided and a \code{repmatrix} is not, or if
#' \code{repmatrix} is set to 0, then only fecundity transitions noted in the
#' supplement will be set to non-zero values. To use the default behavior of
#' setting all reproductive stages to reproduce at full fecundity into immature
#' and propagule stages but also incorporate given or proxy survival
#' transitions, input those given and proxy transitions through the
#' \code{overwrite} options.
#' 
#' The reproduction matrix (field \code{repmatrix}) may only be supplied as
#' ahistorical. If provided as historical, then \code{rlefko2()} will fail and
#' produce an error.
#' 
#' Users may at times wish to estimate MPMs using a dataset incorporating
#' multiple patches or subpopulations. Should the aim of analysis be a general
#' MPM that does not distinguish these patches or subpopulations, the
#' \code{patchcol} variable should be left to \code{NA}, which is the default.
#' Otherwise the variable identifying patch needs to be named.
#'
#' Input options including multiple variable names must be entered in the order
#' of variables in occasion \emph{t}+1 and \emph{t}. Rearranging the order WILL
#' lead to erroneous calculations, and may lead to fatal errors.
#' 
#' Although this function is capable of assigning stages given an input
#' stageframe, it lacks the power of \code{\link{verticalize3}()} and
#' \code{\link{historicalize3}()} in this regard. Users are strongly
#' encouraged to use the latter two functions for stage assignment.
#' 
#' @seealso \code{\link{mpm_create}()}
#' @seealso \code{\link{flefko3}()}
#' @seealso \code{\link{flefko2}()}
#' @seealso \code{\link{aflefko2}()}
#' @seealso \code{\link{fleslie}()}
#' @seealso \code{\link{rlefko3}()}
#' @seealso \code{\link{rlefko2}()}
#' @seealso \code{\link{rleslie}()}
#' 
#' @examples
#' \donttest{
#' # Cypripedium example
#' data(cypdata)
#' 
#' sizevector <- c(0, 0, 0, 0, 0, 0, 1, 2.5, 4.5, 8, 17.5)
#' stagevector <- c("SD", "P1", "P2", "P3", "SL", "D", "XSm", "Sm", "Md", "Lg",
#'   "XLg")
#' repvector <- c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
#' obsvector <- c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
#' matvector <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
#' immvector <- c(0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#' indataset <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
#' binvec <- c(0, 0, 0, 0, 0, 0.5, 0.5, 1, 1, 2.5, 7)
#' minagevec <- c(1, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5)
#' maxagevec <- c(rep(NA, 11))
#' 
#' cypframe_raw <- sf_create(sizes = sizevector, stagenames = stagevector,
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector,
#'   propstatus = propvector, immstatus = immvector, indataset = indataset,
#'   binhalfwidth = binvec, minage = minagevec, maxage = maxagevec)
#' 
#' cypraw_v1 <- verticalize3(data = cypdata, noyears = 6, firstyear = 2004,
#'   patchidcol = "patch", individcol = "plantid", blocksize = 4,
#'   sizeacol = "Inf2.04", sizebcol = "Inf.04", sizeccol = "Veg.04",
#'   repstracol = "Inf.04", repstrbcol = "Inf2.04", fecacol = "Pod.04",
#'   stageassign = cypframe_raw, stagesize = "sizeadded", NAas0 = TRUE,
#'   NRasRep = TRUE, age_offset = 4)
#' 
#' # Here we use supplemental() to provide overwrite and reproductive info
#' cypsupp2r <- supplemental(stage3 = c("SD", "P1", "P2", "P3", "SL", "D", 
#'     "XSm", "Sm", "SD", "P1"),
#'   stage2 = c("SD", "SD", "P1", "P2", "P3", "SL", "SL", "SL", "rep",
#'     "rep"),
#'   eststage3 = c(NA, NA, NA, NA, NA, "D", "XSm", "Sm", NA, NA),
#'   eststage2 = c(NA, NA, NA, NA, NA, "XSm", "XSm", "XSm", NA, NA),
#'   givenrate = c(0.10, 0.20, 0.20, 0.20, 0.25, NA, NA, NA, NA, NA),
#'   multiplier = c(NA, NA, NA, NA, NA, NA, NA, NA, 0.5, 0.5),
#'   type =c(1, 1, 1, 1, 1, 1, 1, 1, 3, 3),
#'   stageframe = cypframe_raw, historical = FALSE, agebased = TRUE)
#' 
#' cyp_mats <- arlefko2(data = cypraw_v1, stageframe = cypframe_raw, year = "all", 
#'   patch = NA, censor = FALSE, stages = c("stage3", "stage2", "stage1"),
#'   size = c("size3added", "size2added"), fec = c("feca3", "feca2"),
#'   supplement = cypsupp2r, agecol = "obsage", yearcol = "year2", 
#'   patchcol = "patchid", indivcol = "individ", prebreeding = TRUE, final_age = NA,
#'   continue = TRUE, reduce = FALSE)
#' }
#' @export
arlefko2 <- function(data, stageframe, year = "all", pop = NULL, patch = NULL,
  censor = FALSE, stages = NULL, alive = c("alive3", "alive2"), obsst = NULL,
  size = c("sizea3", "sizea2"), sizeb = NULL, sizec = NULL,
  repst = c("repstatus3", "repstatus2"), matst = c("matstatus3", "matstatus2"),
  fec = c("feca3", "feca2"), supplement = NULL, repmatrix = NULL,
  overwrite = NULL, agecol = "obsage", yearcol = NULL, popcol = NULL, patchcol = NULL,
  indivcol = NULL, censorcol = NULL, censorkeep = 0, final_age = NA,
  continue = TRUE, prebreeding = TRUE, NRasRep = FALSE, reduce = FALSE, simple = FALSE,
  err_check = FALSE, sparse_output = FALSE) {

  output <- mpm_create(historical = FALSE, stage = TRUE, age = TRUE,
    reduce = reduce, data = data, year = year, pop = pop,
    patch = patch, stageframe = stageframe, supplement = supplement, 
    overwrite = overwrite, repmatrix = repmatrix, alive = alive,
    obsst = obsst, size = size, sizeb = sizeb, sizec = sizec, repst = repst,
    matst = matst, fec = fec, stages = stages, yearcol = yearcol,
    popcol = popcol, patchcol = patchcol, indivcol = indivcol, agecol = agecol,
    censorcol = censorcol, censor = censor, censorkeep = censorkeep,
    last_age = final_age, cont = continue, prebreeding = prebreeding,
    stage_NRasRep = NRasRep, simple = simple, err_check = err_check,
    sparse_output = sparse_output)
  
  return(output)
}

#' Create Raw Leslie (Age-based) Matrix Projection Model
#'
#' Function \code{rleslie()} returns raw Leslie MPMs, including the
#' associated component transition and fecundity matrices, a data frame
#' describing the ages used, and a data frame describing the population, patch,
#' and occasion time associated with each matrix.
#' 
#' @name rleslie
#' 
#' @param data A vertical demographic data frame, with variables corresponding 
#' to the naming conventions in \code{\link{verticalize3}()}.
#' @param start_age The age from which to start the matrix. Defaults to
#' \code{NA}, age \code{1} is used if \code{prebreeding = TRUE}, and age
#' \code{0} is used if \code{prebreeding = FALSE}.
#' @param last_age The final age to use in the matrix. Defaults to \code{NA}, in
#' which case the highest age in the dataset is used.
#' @param continue A logical value designating whether to allow continued
#' survival of individuals past the final age noted in the stageframe, using the 
#' demographic characteristics of the final age. Defaults to \code{TRUE}.
#' @param fecage_min The minimum age at which reproduction is possible. Defaults
#' to \code{NA}, which is interpreted to mean that fecundity should be assessed
#' starting in the minimum age observed in the dataset.
#' @param fecage_max The maximum age at which reproduction is possible. Defaults
#' to \code{NA}, which is interpreted to mean that fecundity should be assessed
#' until the final observed age.
#' @param alive A vector of names of binomial variables corresponding to status
#' as alive (\code{1}) or dead (\code{0}) in occasions \emph{t}+1 ans \emph{t},
#' respectively.
#' @param repst A vector of names of variables coding reproductive status in
#' occasions \emph{t}+1 and \emph{t}, respectively. Defaults to 
#' \code{c("repstatus3", "repstatus2")}.
#' @param fec A vector of names of variables coding fecundity in occasions
#' \emph{t}+1 and \emph{t}, respectively. Defaults to \code{c("feca3", "feca2")}.
#' @param agecol The name or column number of the variable coding for age in
#' \code{data}. Defaults to \code{"obsage"}.
#' @param year A variable corresponding to observation occasion, or a set
#' of such values, given in values associated with the \code{year} term used in
#' vital rate model development. Can also equal \code{"all"}, in which case
#' matrices will be estimated for all occasion times. Defaults to \code{"all"}.
#' @param supplement An optional data frame of class \code{lefkoSD} that
#' provides supplemental data that should be incorporated into the MPM. Three
#' kinds of data may be integrated this way: transitions to be estimated via the
#' use of proxy transitions, transition overwrites from the literature or
#' supplemental studies, and transition multipliers for survival and fecundity.
#' This data frame should be produced using the \code{\link{supplemental}()}
#' function.
#' @param pop A variable designating which populations will have matrices
#' estimated. Should be set to specific population names, or to \code{"all"} if
#' all populations should have matrices estimated.
#' @param patch A variable designating which patches or subpopulations will have
#' matrices estimated. Should be set to specific patch names, or to \code{"all"}
#' if matrices should be estimated for all patches. Defaults to \code{"all"}.
#' @param yearcol The variable name or column number corresponding to occasion 
#' \emph{t} in the dataset.
#' @param popcol The variable name or column number corresponding to the
#' identity of the population.
#' @param patchcol The variable name or column number corresponding to patch in
#' the dataset.
#' @param indivcol The variable name or column number coding individual
#' identity.
#' @param censor If \code{TRUE}, then data will be removed according to the
#' variable set in \code{censorcol}, such that only data with censor values
#' equal to \code{censorkeep} will remain. Defaults to \code{FALSE}.
#' @param censorcol The variable name or column number denoting the censor
#' status. Only needed if \code{censor = TRUE}.
#' @param censorkeep The value of the censor variable denoting data elements to
#' keep. Defaults to \code{0}.
#' @param fectime An integer indicating whether to estimate fecundity using
#' the variable given for \code{fec} in time \emph{t} (\code{2}) or time
#' \emph{t}+1 (\code{3}).
#' @param fecmod A scalar multiplier for fecundity. Defaults to \code{1.0}.
#' @param prebreeding A logical value indicating whether the life history model
#' is a pre-breeding model. Defaults to \code{TRUE}.
#' @param reduce A logical value denoting whether to remove ages associated with
#' only zero transitions. These are removed only if the respective row and
#' column sums in ALL matrices estimated equal 0. Defaults to \code{FALSE}, and
#' should generally not be used in age-based MPMs.
#' @param simple A logical value indicating whether to produce \code{A},
#' \code{U}, and \code{F} matrices, or only the latter two. Defaults to
#' \code{FALSE}, in which case all three are output.
#' @param err_check A logical value indicating whether to append extra
#' information used in matrix calculation within the output list. Defaults to
#' \code{FALSE}.
#' @param sparse_output A logical value indicating whether to output matrices
#' in sparse format. Defaults to \code{FALSE}, in which case all matrices are
#' output in standard matrix format.
#' 
#' @return If all inputs are properly formatted, then this function will return
#' an object of class \code{lefkoMat}, which is a list that holds the matrix
#' projection model and all of its metadata. Its structure is a list with the
#' following elements:
#' 
#' \item{A}{A list of full projection matrices in order of sorted populations,
#' patches, and occasions. All matrices output in the \code{matrix} class, or in
#' the \code{dgCMatrix} class from the \code{Matrix} package if sparse.}
#' \item{U}{A list of survival transition matrices sorted as in \code{A}. All 
#' matrices output in the \code{matrix} class, or in the \code{dgCMatrix} class
#' from the \code{Matrix} package if sparse.}
#' \item{F}{A list of fecundity matrices sorted as in \code{A}. All matrices 
#' output in the \code{matrix} class, or in the \code{dgCMatrix} class from the
#' \code{Matrix} package if sparse.}
#' \item{hstages}{A data frame matrix showing the pairing of ahistorical stages
#' used to create historical stage pairs. Set to NA for ahistorical matrices.}
#' \item{agestages}{A data frame showing age-stage pairs. In this function, it
#' is set to NA. Only used in output to function \code{aflefko2}().}
#' \item{ahstages}{A data frame detailing the characteristics of associated
#' ahistorical stages, in the form of a modified stageframe that includes
#' status as an entry stage through reproduction.}
#' \item{labels}{A data frame giving the population, patch, and year of each 
#' matrix in order.}
#' \item{dataqc}{A vector showing the numbers of individuals and rows in the
#' vertical dataset used as input.}
#' \item{matrixqc}{A short vector describing the number of non-zero elements in
#' \code{U} and \code{F} matrices, and the number of annual matrices.}
#' \item{modelqc}{This is the \code{qc} portion of the \code{modelsuite} input
#' in function-based MPMs. Empty in this function.}
#'
#' @section Notes:
#' In order to accomodate survival to time \emph{t}+1 in the final year of a
#' study, the maximum age assessed if no input \code{last_age} is provided is
#' one time step past the final described age.
#' 
#' Users may at times wish to estimate MPMs using a dataset incorporating
#' multiple patches or subpopulations. Should the aim of analysis be a general
#' MPM that does not distinguish these patches or subpopulations, the
#' \code{patchcol} variable should be left to \code{NA}, which is the default.
#' Otherwise the variable identifying patch needs to be named.
#'
#' Input options including multiple variable names must be entered in the order
#' of variables in occasion \emph{t}+1 and \emph{t}. Rearranging the order WILL
#' lead to erroneous calculations, and may lead to fatal errors.
#' 
#' @seealso \code{\link{mpm_create}()}
#' @seealso \code{\link{flefko3}()}
#' @seealso \code{\link{flefko2}()}
#' @seealso \code{\link{aflefko2}()}
#' @seealso \code{\link{arlefko2}()}
#' @seealso \code{\link{fleslie}()}
#' @seealso \code{\link{rlefko3}()}
#' @seealso \code{\link{rlefko2}()}
#' 
#' @examples
#' data(cypdata)
#' 
#' cypraw_v1 <- verticalize3(data = cypdata, noyears = 6, firstyear = 2004,
#'   patchidcol = "patch", individcol = "plantid", blocksize = 4,
#'   sizeacol = "Inf2.04", sizebcol = "Inf.04", sizeccol = "Veg.04",
#'   repstracol = "Inf.04", repstrbcol = "Inf2.04", fecacol = "Pod.04",
#'   age_offset = 3, NAas0 = TRUE, NRasRep = TRUE)
#' 
#' cyp_rl <- rleslie(data = cypraw_v1, start_age = 0, last_age = 4,
#'   continue = TRUE, fecage_min = 3, year = "all", pop = NA, patch = "all",
#'   yearcol = "year2", patchcol = "patchid", indivcol = "individ")
#' 
#' @export
rleslie <- function(data, start_age = NA, last_age = NA, continue = TRUE,
  fecage_min = NA, fecage_max = NA, alive = c("alive3", "alive2", "alive1"),
  repst = c("repstatus3", "repstatus2", "repstatus1"),
  fec = c("feca3", "feca2", "feca1"), agecol = "obsage", year = "all",
  supplement = NULL, pop = NULL, patch = NULL, yearcol = NULL, popcol = NULL,
  patchcol = NULL, indivcol = NULL, censor = FALSE, censorcol = NULL,
  censorkeep = 0, fectime = 2, fecmod = 1.0, prebreeding = TRUE, reduce = FALSE,
  simple = FALSE, err_check = FALSE, sparse_output = FALSE) {

  output <- mpm_create(historical = FALSE, stage = FALSE, age = TRUE,
    devries = FALSE, reduce = reduce, data = data, supplement = supplement,
    year = year, pop = pop, patch = patch, alive = alive, repst = repst,
    fec = fec, yearcol = yearcol, popcol = popcol, patchcol = patchcol,
    indivcol = indivcol, agecol = agecol, censorcol = censorcol,
    censor = censor, censorkeep = censorkeep, start_age = start_age,
    last_age = last_age, fecage_min = fecage_min, fecage_max = fecage_max,
    fectime = fectime, fecmod = fecmod, cont = continue, prebreeding = prebreeding,
    simple = simple, err_check = err_check, sparse_output = sparse_output)
  
  return(output)
}

#' Summary of Class "lefkoMat"
#'
#' A function to simplify the viewing of basic information describing the
#' matrices produced through functions \code{\link{flefko3}()},
#' \code{\link{flefko2}()}, \code{\link{rlefko3}()}, \code{\link{rlefko2}()},
#' \code{\link{aflefko2}()}, \code{\link{rleslie}()}, and
#' \code{\link{fleslie}()}.
#' 
#' @name summary.lefkoMat
#' 
#' @param object An object of class \code{lefkoMat}.
#' @param colsums A logical value indicating whether column sums should be shown
#' for U matrices, allowing users to check stage survival probabilities.
#' Defaults to TRUE.
#' @param ... Other parameters.
#' 
#' @return A summary of the object, showing the number of each type of matrix,
#' the number of annual matrices, the number of estimated (non-zero) elements
#' across all matrices and per matrix, the number of unique transitions in the
#' dataset, the number of individuals, and summaries of the column sums of the
#' survival-transition matrices. This function will also yield warnings if any
#' survival-transition matrices include elements outside of the interval [0,1],
#' if any fecundity matrices contain negative elements, and if any matrices
#' include NA values.
#' 
#' @section Notes:
#' Under the Gaussian and gamma size distributions, the number of estimated
#' parameters may differ between the two \code{ipm_method} settings. Because
#' the midpoint method has a tendency to incorporate upward bias in the
#' estimation of size transition probabilities, it is more likely to yield non-
#' zero values when the true probability is extremely close to 0. This will
#' result in the \code{summary.lefkoMat} function yielding higher numbers of
#' estimated parameters than the \code{ipm_method = "CDF"} yields in some cases.
#' 
#' @examples
#' data(cypdata)
#' 
#' sizevector <- c(0, 0, 0, 0, 0, 0, 1, 2.5, 4.5, 8, 17.5)
#' stagevector <- c("SD", "P1", "P2", "P3", "SL", "D", "XSm", "Sm", "Md", "Lg",
#'   "XLg")
#' repvector <- c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
#' obsvector <- c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
#' matvector <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
#' immvector <- c(0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
#' propvector <- c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#' indataset <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
#' binvec <- c(0, 0, 0, 0, 0, 0.5, 0.5, 1, 1, 2.5, 7)
#' 
#' cypframe_raw <- sf_create(sizes = sizevector, stagenames = stagevector,
#'   repstatus = repvector, obsstatus = obsvector, matstatus = matvector,
#'   propstatus = propvector, immstatus = immvector, indataset = indataset,
#'   binhalfwidth = binvec)
#' 
#' cypraw_v1 <- verticalize3(data = cypdata, noyears = 6, firstyear = 2004,
#'   patchidcol = "patch", individcol = "plantid", blocksize = 4,
#'   sizeacol = "Inf2.04", sizebcol = "Inf.04", sizeccol = "Veg.04",
#'   repstracol = "Inf.04", repstrbcol = "Inf2.04", fecacol = "Pod.04",
#'   stageassign = cypframe_raw, stagesize = "sizeadded", NAas0 = TRUE,
#'   NRasRep = TRUE)
#' 
#' # Here we use supplemental() to provide overwrite and reproductive info
#' cypsupp2r <- supplemental(stage3 = c("SD", "P1", "P2", "P3", "SL", "D", 
#'     "XSm", "Sm", "SD", "P1"),
#'   stage2 = c("SD", "SD", "P1", "P2", "P3", "SL", "SL", "SL", "rep",
#'     "rep"),
#'   eststage3 = c(NA, NA, NA, NA, NA, "D", "XSm", "Sm", NA, NA),
#'   eststage2 = c(NA, NA, NA, NA, NA, "XSm", "XSm", "XSm", NA, NA),
#'   givenrate = c(0.10, 0.20, 0.20, 0.20, 0.25, NA, NA, NA, NA, NA),
#'   multiplier = c(NA, NA, NA, NA, NA, NA, NA, NA, 0.5, 0.5),
#'   type =c(1, 1, 1, 1, 1, 1, 1, 1, 3, 3),
#'   stageframe = cypframe_raw, historical = FALSE)
#' 
#' cypmatrix2r <- rlefko2(data = cypraw_v1, stageframe = cypframe_raw, 
#'   year = "all", patch = "all", stages = c("stage3", "stage2", "stage1"),
#'   size = c("size3added", "size2added"), supplement = cypsupp2r,
#'   yearcol = "year2", patchcol = "patchid", indivcol = "individ")
#' 
#' summary(cypmatrix2r)
#' 
#' @export
summary.lefkoMat <- function(object, colsums = TRUE, ...) {
  
  matrices <- object
  
  matdim <- dim(matrices$A[[1]])[1]
  
  mqca <- matrices$matrixqc[1]
  mqcb <- matrices$matrixqc[2]
  mqcc <- matrices$matrixqc[3]
  
  totalpops <- length(unique(matrices$labels$pop))
  totalpatches <- length(unique(matrices$labels$patch))
  totalyears <- length(unique(matrices$labels$year2))
  
  if (!all(is.na(matrices$hstages))) {
    histmark <- "historical"
  } else {
    histmark <- "ahistorical"
  }
  
  if (mqcc == 1) {
    writeLines(paste0("\nThis ", histmark, " lefkoMat object contains ", mqcc,
        " matrix."))
  } else {
    writeLines(paste0("\nThis ", histmark, " lefkoMat object contains ", mqcc,
        " matrices."))
  }
  writeLines(paste0("\nEach matrix is square with ", matdim,
    " rows and columns, and a total of ", matdim*matdim, " elements."))
  
  mqac <- mqca / mqcc
  if (mqac != floor(mqac)) mqac <- round(mqac, digits = 3)
  
  if (!all(is.na(mqac))) {
    mqbc <- mqcb / mqcc
    if (mqbc != floor(mqbc)) mqbc <- round(mqbc, digits = 3)
    
    writeLines(paste0("A total of ", mqca, " survival transitions were estimated, with ", 
        mqac, " per matrix."))
    writeLines(paste0("A total of ", mqcb, " fecundity transitions were estimated, with ", 
        mqbc, " per matrix."))
  } else {
    writeLines(paste0("A total of ", mqca, " transitions were estimated, with ", 
        mqac, " per matrix. Positions of survival vs fecundity transitions are not known."))
  }
  
  grammar_pops <- " populations, "
  grammar_patches <- " patches, and "
  grammar_years <- " time steps."
  if (totalpops == 1) grammar_pops <- " population, "
  if (totalpatches == 1) grammar_patches <- " patch, and "
  if (totalyears == 1) grammar_years <- " time step."
  
  writeLines(paste0("This lefkoMat object covers ", totalpops, grammar_pops,
      totalpatches, grammar_patches, totalyears, grammar_years))
  
  if (is.element("dataqc", names(matrices))) {
    dqca <- matrices$dataqc[1]
    dqcb <- matrices$dataqc[2]
    
    if (!is.na(dqca) & !is.na(dqcb)) {
      writeLines(paste0("\nThe dataset contains a total of ", dqca, " unique individuals and ", dqcb, " unique transitions."))
    } else if (!is.na(dqca)) {
      writeLines(paste0("\nThe dataset contains a total of ", dqca, " unique individuals. Number of unique transitions not known."))
    } else if (!is.na(dqcb)) {
      writeLines(paste0("\nThe dataset contains a total of ", dqcb, " unique transitions. Number of unique individuals not known."))
    } else {
      writeLines("\nThis lefkoMat object appears to have been imported. Number of unique individuals and transitions not known.")
    }
  }
  
  if (is.element("modelqc", names(matrices))) {
    if (is.data.frame(matrices$modelqc) & dim(matrices$modelqc)[1] > 0) {
      moqc12 <- matrices$modelqc[1,2]
      moqc22 <- matrices$modelqc[2,2]
      moqc32 <- matrices$modelqc[3,2]
      moqc42 <- matrices$modelqc[4,2]
      moqc52 <- matrices$modelqc[5,2]
      moqc62 <- matrices$modelqc[6,2]
      moqc72 <- matrices$modelqc[7,2]
      moqc82 <- matrices$modelqc[8,2]
      moqc92 <- matrices$modelqc[9,2]
      moqc102 <- matrices$modelqc[10,2]
      moqc112 <- matrices$modelqc[11,2]
      moqc122 <- matrices$modelqc[12,2]
      moqc132 <- matrices$modelqc[13,2]
      moqc142 <- matrices$modelqc[14,2]
      
      moqc13 <- matrices$modelqc[1,3]
      moqc23 <- matrices$modelqc[2,3]
      moqc33 <- matrices$modelqc[3,3]
      moqc43 <- matrices$modelqc[4,3]
      moqc53 <- matrices$modelqc[5,3]
      moqc63 <- matrices$modelqc[6,3]
      moqc73 <- matrices$modelqc[7,3]
      moqc83 <- matrices$modelqc[8,3]
      moqc93 <- matrices$modelqc[9,3]
      moqc103 <- matrices$modelqc[10,3]
      moqc113 <- matrices$modelqc[11,3]
      moqc123 <- matrices$modelqc[12,3]
      moqc133 <- matrices$modelqc[13,3]
      moqc143 <- matrices$modelqc[14,3]
      
      writeLines("\nVital rate modeling quality control:\n")
      
      if (moqc12 > 0) {
        writeLines(paste0("Survival estimated with ", moqc12, " individuals and ", moqc13, " individual transitions."))
      } else {
        writeLines("Survival not estimated.")
      }
      
      if (moqc22 > 0) {
        writeLines(paste0("Observation estimated with ", moqc22, " individuals and ", moqc23, " individual transitions."))
      } else {
        writeLines("Observation probability not estimated.")
      }
      
      if (moqc32 > 0) {
        writeLines(paste0("Primary size estimated with ", moqc32, " individuals and ", moqc33, " individual transitions."))
      } else {
        writeLines("Primary size transition not estimated.")
      }
      
      if (moqc42 > 0) {
        writeLines(paste0("Secondary size estimated with ", moqc42, " individuals and ", moqc43, " individual transitions."))
      } else {
        writeLines("Secondary size transition not estimated.")
      }
      
      if (moqc52 > 0) {
        writeLines(paste0("Tertiary size estimated with ", moqc52, " individuals and ", moqc53, " individual transitions."))
      } else {
        writeLines("Tertiary size transition not estimated.")
      }
      
      if (moqc62 > 0) {
        writeLines(paste0("Reproductive status estimated with ", moqc62, " individuals and ", moqc63, " individual transitions."))
      } else {
        writeLines("Reproduction probability not estimated.")
      }
      
      if (moqc72 > 0) {
        writeLines(paste0("Fecundity estimated with ", moqc72, " individuals and ", moqc73, " individual transitions."))
      } else {
        writeLines("Fecundity not estimated.")
      }
      
      if (moqc82 > 0) {
        writeLines(paste0("Juvenile survival estimated with ", moqc82, " individuals and ", moqc83, " individual transitions."))
      } else {
        writeLines("Juvenile survival not estimated.")
      }
      
      if (moqc92 > 0) {
        writeLines(paste0("Juvenile observation estimated with ", moqc92, " individuals and ", moqc93, " individual transitions."))
      } else {
        writeLines("Juvenile observation probability not estimated.")
      }
      
      if (moqc102 > 0) {
        writeLines(paste0("Juvenile primary size estimated with ", moqc102, " individuals and ", moqc103, " individual transitions."))
      } else {
        writeLines("Juvenile primary size transition not estimated.")
      }
      
      if (moqc112 > 0) {
        writeLines(paste0("Juvenile secondary size estimated with ", moqc112, " individuals and ", moqc113, " individual transitions."))
      } else {
        writeLines("Juvenile secondary size transition not estimated.")
      }
      
      if (moqc122 > 0) {
        writeLines(paste0("Juvenile tertiary size estimated with ", moqc122, " individuals and ", moqc123, " individual transitions."))
      } else {
        writeLines("Juvenile tertiary size transition not estimated.")
      }
      
      if (moqc132 > 0) {
        writeLines(paste0("Juvenile reproduction estimated with ", moqc132, " individuals and ", moqc133, " individual transitions."))
      } else {
        writeLines("Juvenile reproduction probability not estimated.")
      }
      
      if (moqc142 > 0) {
        writeLines(paste0("Juvenile maturity transition estimated with ", moqc142, " individuals and ", moqc143, " individual transitions."))
      } else {
        writeLines("Juvenile maturity transition probability not estimated.")
      }
    }
  }
  
  dethonthetoilet <- apply(as.matrix(c(1:length(matrices$U))), 1, function(X) {
      if (is(matrices$U[[1]], "dgCMatrix")) {  
        summary(Matrix::colSums(matrices$U[[X]]))
      } else {
        summary(colSums(matrices$U[[X]]))
      }
    }
  )
  
  sexinthelavatory <- apply(as.matrix(c(1:length(matrices$U))), 1, function(X) {
      summary(colSums(matrices$F[[X]]))
    }
  )
  
  dethintheurinal <- apply(as.matrix(c(1:length(matrices$U))), 1, function(X) {
      any(is.na(matrices$A[[X]]))
    }
  )
  
  if (colsums) {
    writeLines("\nSurvival probability sum check (each matrix represented by column in order):")
    print(dethonthetoilet, digits = 3)
  }
  
  if (max(dethonthetoilet) > 1) {
    warning("Some matrices include stages with survival probability greater than 1.0.", call. = FALSE)
  }
  
  if (min(dethonthetoilet) < 0) {
    warning("Some matrices include stages with survival probability less than 0.0.", call. = FALSE)
  }
  
  if (min(sexinthelavatory) < 0) {
    warning("Some matrices include stages with fecundity less than 0.0.", call. = FALSE)
  }
  
  if (any(dethintheurinal)) {
    warning("Some matrices include NA values.", call. = FALSE)
  }
}

Try the lefko3 package in your browser

Any scripts or data that you put into this service are public.

lefko3 documentation built on Oct. 14, 2023, 1:07 a.m.