Volume 12, Issue 10 p. 1826-1834
Open Access

ipmr: Flexible implementation of Integral Projection Models in R

Sam C. Levin

Corresponding Author

Sam C. Levin

Institute of Biology, Martin Luther University Halle-Wittenberg, Halle (Saale), Germany

German Centre for Integrative Biodiversity Research (iDiv) Halle-Jena-Leipzig, Leipzig, Germany

Department of Zoology, University of Oxford, Oxford, UK


Sam C. Levin

Email: [email protected]

Search for more papers by this author
Dylan Z. Childs

Dylan Z. Childs

Department of Animal and Plant Sciences, University of Sheffield, Sheffield, UK

Search for more papers by this author
Aldo Compagnoni

Aldo Compagnoni

Institute of Biology, Martin Luther University Halle-Wittenberg, Halle (Saale), Germany

German Centre for Integrative Biodiversity Research (iDiv) Halle-Jena-Leipzig, Leipzig, Germany

Department of Zoology, University of Oxford, Oxford, UK

Search for more papers by this author
Sanne Evers

Sanne Evers

Institute of Biology, Martin Luther University Halle-Wittenberg, Halle (Saale), Germany

German Centre for Integrative Biodiversity Research (iDiv) Halle-Jena-Leipzig, Leipzig, Germany

Department of Community Ecology, Helmholtz Centre for Environmental Research-UFZ, Halle (Saale), Germany

Search for more papers by this author
Tiffany M. Knight

Tiffany M. Knight

Institute of Biology, Martin Luther University Halle-Wittenberg, Halle (Saale), Germany

German Centre for Integrative Biodiversity Research (iDiv) Halle-Jena-Leipzig, Leipzig, Germany

Department of Community Ecology, Helmholtz Centre for Environmental Research-UFZ, Halle (Saale), Germany

Search for more papers by this author
Roberto Salguero-Gómez

Roberto Salguero-Gómez

Department of Zoology, University of Oxford, Oxford, UK

Search for more papers by this author
First published: 22 July 2021
Citations: 3

'Tiffany M. Knight and Roberto Salguero-Gómez contributed equally to this work

Handling Editor: Giovanni Strona

Funding information

R.S.-G. was supported by a NERC Independent Research Fellowship (NE/M018458/1). S.C.L., A.C., S.E. and T.M.K. were funded by the Alexander von Humboldt Foundation in the framework of the Alexander von Humboldt Professorship of TM Knight endowed by the German Federal Ministry of Education and Research.


  1. Integral projection models (IPMs) are an important tool for studying the dynamics of populations structured by one or more continuous traits (e.g. size, height, body mass). Researchers use IPMs to investigate questions ranging from linking drivers to population dynamics, planning conservation and management strategies, and quantifying selective pressures in natural populations. The popularity of stage-structured population models has been supported by R scripts and packages (e.g. IPMpack, popbio, popdemo, lefko3) aimed at ecologists, which have introduced a broad repertoire of functionality and outputs. However, pressing ecological, evolutionary and conservation biology topics require developing more complex IPMs, and considerably more expertise to implement them. Here, we introduce ipmr, a flexible R package for building, analysing and interpreting IPMs.
  2. The ipmr framework relies on the mathematical notation of the models to express them in code format. Additionally, this package decouples the model parameterization step from the model implementation step. The latter point substantially increases ipmr's flexibility to model complex life cycles and demographic processes.
  3. ipmr can handle a wide variety of models, including those that incorporate density dependence, discretely and continuously varying stochastic environments, and multiple continuous and/or discrete traits. ipmr can accommodate models with individuals cross-classified by age and size. Furthermore, the package provides methods for demographic analyses (e.g. asymptotic and stochastic growth rates) and visualization (e.g. kernel plotting).
  4. ipmr is a flexible R package for integral projection models. The package substantially reduces the amount of time required to implement general IPMs. We also provide extensive documentation with six vignettes and help files, accessible from an R session and online.


Integral projection models (IPMs) are an important and widely used tool for ecologists studying structured population dynamics in discrete time. Since the paper introducing IPMs was published over two decades ago (Easterling et al., 2000), at least 255 peer-reviewed publications on at least 250 plant species and 60 animal species have used IPMs (ESM, Table S1; Figure S1). These models have addressed questions ranging from invasive species population dynamics (e.g. Crandall & Knight, 2017), effect of climate drivers on population persistence (e.g. Compagnoni et al., 2021), evolutionary stable strategies (e.g. Childs et al., 2004) and rare/endangered species conservation (e.g. Ferrer-Cervantes et al., 2012).

The IPM was introduced as alternative to matrix population models, which model populations structured by discrete traits (Caswell, 2001). Some of the advantages of using an IPM include (a) the ability to model populations structured by continuously distributed traits, (b) the ability to flexibly incorporate discrete and continuous traits in the same model (e.g. seeds in a seedbank and a height-structured plant population, Crandall & Knight, 2017, or number of females, males and age-1 recruits for fish species, Erickson et al., 2017), (c) efficient parameterization of demographic processes with familiar regression methods (Coulson, 2012), and (d) the numerical discretization of continuous kernels (see below) means that the tools available for matrix population models are usually also applicable for IPMs. Furthermore, researchers have developed methods to incorporate spatial dynamics (Jongejans et al., 2011), environmental stochasticity (Rees & Ellner, 2009) and density/frequency dependence into IPMs (Adler et al., 2010; Ellner et al., 2016). These developments were accompanied by the creation of software tools and guides to assist with IPM parameterization, implementation and analysis. These tools range from R scripts with detailed annotations (Coulson, 2012; Ellner et al., 2016; Merow et al., 2014) to R packages (Metcalf et al., 2013; Shefferson et al., 2020).

Despite the array of resources available to researchers, implementing an IPM is still not a straightforward exercise. For example, an IPM that simulates a population for 100 time steps requires the user to either write or adapt from published guides multiple functions (e.g. to summarize demographic functions into the proper format), implement the numerical approximations of the model's integrals, ensure that individuals are not accidentally sent beyond the integration bounds (‘unintentional eviction’, sensu Williams et al., 2012) and track how the population state changes over the course of a simulation. Stochastic IPMs present further implementation challenges. In addition to the aforementioned elements, users must generate the sequence of environments that the population experiences. There are multiple ways of simulating environmental stochasticity, each with their own strengths and weaknesses (Metcalf et al., 2015).

ipmr manages these key details while providing the user flexibility in their models. ipmr uses the rlang package for metaprogramming (Henry & Wickham, 2020), which enables ipmr to provide a miniature domain-specific language for implementing IPMs. ipmr aims to mimic the mathematical syntax that describes IPMs as closely as possible (Figure 1; Box 1; Tables 1 and 2). This R package can handle models with individuals classified by a mixture of any number of continuously and discretely distributed traits. Furthermore, ipmr introduces specific classes and methods to deal with both discretely and continuously varying stochastic environments, density-independent and -dependent models, as well as age-structured populations (Case Study 2). ipmr decouples the parameterization (i.e. regression model fitting) and implementation steps (i.e. converting the regression parameters into a full IPM), and does not attempt to help users with the parameterization task. This provides greater flexibility in modelling trait–demography relationships, and enables users to specify IPMs of any functional form that they desire.

Details are in the caption following the image
There are generally six steps in defining an IPM with ipmr. (1) Vital rate models are fit to demographic data collected from field sites. This step requires the use of other packages, as ipmr does not contain facilities for regression modelling. The figure on the left shows the fitted relationship between size at urn:x-wiley:2041210X:media:mee313683:mee313683-math-0001 and urn:x-wiley:2041210X:media:mee313683:mee313683-math-0002 for Carpobrotus spp. in Case Study 1. (2) The next step is deciding what type of IPM is needed. This is determined by both the research question and the data used to parameterize the regression models. This process is initiated with init_ipm(). In step (3), kernels are defined using ipmr's syntax to represent kernels and vital rate functions. (4) Having defined symbolic representations of the model, the numerical definition is given. Here, the integration rule, domain bounds and initial population conditions are defined. For some models, initial environmental conditions can also be defined. (5) make_ipm() numerically implements the proto_ipm object, (6) which can then be analysed further. The figure at the bottom left shows a urn:x-wiley:2041210X:media:mee313683:mee313683-math-0003 kernel created by make_ipm() and make_iter_kernel(). The line plots above and to the right display the left and right eigenvectors, extracted with left_ev() and right_ev(), respectively
TABLE 1. Translations between mathematical notation, R’s formula notation and ipmr's notation for the simplified version of Bogdan et al.'s Carpobrotus IPM. The ipmr column contains the expressions used in each kernel's definition. R expressions are not provided for sub-kernels and model iteration procedures because they typically require defining functions separately, and there are many ways to do this step (examples are in the R code for each case study in the appendix). The plogis() function computes the inverse logit transformation of an expression. urn:x-wiley:2041210X:media:mee313683:mee313683-math-0004 corresponds to survival, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0005 corresponds to change in size conditional on survival, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0006 is the probability of reproducing, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0007 is the number of propagules produced by reproductive individuals and urn:x-wiley:2041210X:media:mee313683:mee313683-math-0008 is the probability that a propagule becomes a new recruit at urn:x-wiley:2041210X:media:mee313683:mee313683-math-0009
Math formula R formula ipmr
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0010 size_2 ~ size_1, family =gaussian() mu_G = G_int + G_slope * z
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0011 G = dnorm(z_2, mu_G, sd_G) G = dnorm(z_2, mu_G, sd_G)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0012 surv ~size_1, family = binomial() s = plogis(s_int + s_slope * z)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0013 fec ~size_1, family = poisson() r_n = exp(r_n_int + r_n_slope * z)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0014 repr ~ size_1, family = binomial() r_p = plogis(r_p_int + r_p_slope * z)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0015 dnorm(z_2, mu_f_d, sigma_f_d) r_d = dnorm(z_2, f_d_mu, f_d_sigma)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0016 p_r = n_new_recruits / n_flowers p_r = n_new / n_flowers
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0017 P = s * G
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0018 F = r_p * r_n * r_d * p_r
TABLE 2. Translations between mathematical notation, R’s formula notation and ipmr's notation for Ellner et al. (2016) Ovis aries IPM. The ipmr column contains the expressions used in each kernel's definition. R expressions are not provided for sub-kernels and model iteration procedures because they typically require defining functions separately, and there are many ways to do this step (examples are in the R code for each case study in the appendix). ipmr supports a suffix based syntax to avoid repetitively typing out the levels of discrete grouping variables. These are represented as ‘a’ in the Math column, ‘age’ in the R formula column, and are highlighted in bold in the ipmr column. urn:x-wiley:2041210X:media:mee313683:mee313683-math-0020 corresponds to survival, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0021 corresponds to change in size conditional on survival, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0022 is the probability of mating, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0023 is the probability that a mating produces a new recruit at urn:x-wiley:2041210X:media:mee313683:mee313683-math-0024 and urn:x-wiley:2041210X:media:mee313683:mee313683-math-0025 is the size distribution of new recruits at urn:x-wiley:2041210X:media:mee313683:mee313683-math-0026 whose mean depends on parent size at time urn:x-wiley:2041210X:media:mee313683:mee313683-math-0027. urn:x-wiley:2041210X:media:mee313683:mee313683-math-0028 is divided by 2 because this IPM only tracks females
Math formula R formula ipmr
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0029 surv ~ size_1 + age, family = binomial() s_age = plogis(s_int + s_z * z_1 + s_a * age)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0030 G = dnorm(size_2, mu_G_age, sigma_G) G_age = dnorm(z_2, mu_G_age, sigma_G)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0031 size_2 ~ size_1 + age, family = gaussian() mu_G_age = G_int + G_z * z + G_a * age
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0032 repr ~size_1 + age, family = binomial() m_p_age = plogis(m_p_int + m_p_z * z + m_p_a * age)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0033 recr ~age, family = binomial() r_p_age = plogis(r_p_int + r_p_a * age)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0034 b = dnorm(size_2, mu_rc_size, sigma_rc_size) rc_size = dnorm(z_2, mu_rc_size, sigma_rc_size)
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0035 rc_size_2 ~ size_1, family = gaussian() mu_rc_size = rc_size_int + rc_size_z * z
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0036 P_age = s_age * g_age * d_z
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0037 F_age = s_age * f_p_age * r_p_age * rc_size / 2

BOX 1. Code to implement a simple IPM from parameter estimates in ipmr. Because ipmr does not include functions to assist with regression modelling, this example skips the step of working with actual data and instead uses hypothetical parameter values. We see that given this set of conditions, if nothing were to change, the population would increase by ~2% each year. The case studies provide details on further use cases and analyses that are possible with ipmr.

  • library(ipmr)

  • # This section produces the result of Step 1 in Figure 1.

  • data_list <- list(

  • s_i = -0.65, # Intercept of the survival model (Logistic regression)

  • s_z = 0.75, # Slope of the survival model

  • G_i = 0.96, # Intercept of the growth model (Gaussian regression)

  • G_z = 0.66, # Slope of the growth model

  • sd_G = 0.67, # Standard deviation of residuals of growth model

  • mu_r = -0.08, # Mean of the recruit size distribution

  • sd_r = 0.76, # Standard deviation of the recruit size distribution

  • r_n_i = -1, # Intercept of recruit production model (Poisson regression)

  • r_n_z = 0.3 # Slope of recruit production model.

  • )

  • # Step 2 in Figure 1. This is how ipmr initializes a model object.

  • # All functions prefixed with define_* generate proto_ipm objects. These

  • # are converted into IPMs using the make_ipm() function in step 5.

  • example_proto_ipm <- init_ipm(sim_gen = "simple",

  • di_dd = "di",

  • det_stoch = "det")

  • # Step 3 in Figure 1. Note the link between how the model was defined

  • # mathematically and how it is defined here.

  • example_proto_ipm <- define_kernel(

  • example_proto_ipm,

  • name = "P",

  • formula = surv * Grow,

  • surv = plogis(s_i + s_z * z_1),

  • Grow = dnorm(z_2, mu_G, sd_G),

  • mu_G = G_i + G_z * z_1,

  • data_list = data_list,

  • states = list(c("z"))

  • )

  • example_proto_ipm <- define_kernel(

  • example_proto_ipm,

  • name = "F",

  • formula = recr_number * recr_size,

  • recr_number = exp(r_n_i + r_n_z * z_1),

  • recr_size = dnorm(z_2, mu_r, sd_r),

  • data_list = data_list,

  • states = list(c("z"))

  • )

  • # Step 4 in Figure 1. These next 3 functions define:

  • # 1. The numerical integration rules and how to iterate the

  • # model (define_impl).

  • # 2. The range of values the the trait "z" can take on, and the number of

  • # meshpoints to use when dividing the interval (define_domains).

  • # 3. The initial population state (define_pop_state).

  • example_proto_ipm <- define_impl(

  • example_proto_ipm,

  • list(

  • P = list(int_rule = "midpoint", state_start = "z", state_end = "z"),

  • F = list(int_rule = "midpoint", state_start = "z", state_end = "z")

  • )

  • )

  • example_proto_ipm <- define_domains(

  • example_proto_ipm,

  • z = c(-2.65, 4.5, 250) # format: c(L, U, m), m is number of meshpoints

  • )

  • example_proto_ipm <- define_pop_state(

  • example_proto_ipm,

  • n_z = rep(1/250, 250)

  • )

  • # Step 5 in Figure 1.

  • example_ipm <- make_ipm(example_proto_ipm)

  • # Step 6 in Figure 1.

  • lambda(example_ipm)


An IPM describes how the abundance and distribution of trait values (also called state variables/states, denoted urn:x-wiley:2041210X:media:mee313683:mee313683-math-0041 and urn:x-wiley:2041210X:media:mee313683:mee313683-math-0042) for a population changes in discrete time. The distribution of trait values in a population at time urn:x-wiley:2041210X:media:mee313683:mee313683-math-0043 is given by the function urn:x-wiley:2041210X:media:mee313683:mee313683-math-0044. A simple IPM for the trait distribution urn:x-wiley:2041210X:media:mee313683:mee313683-math-0045 at time urn:x-wiley:2041210X:media:mee313683:mee313683-math-0046 is then
urn:x-wiley:2041210X:media:mee313683:mee313683-math-0048, known as the projection kernel, describes all possible transitions of existing individuals and recruitment of new individuals from urn:x-wiley:2041210X:media:mee313683:mee313683-math-0049 to urn:x-wiley:2041210X:media:mee313683:mee313683-math-0050, generating a new trait distribution urn:x-wiley:2041210X:media:mee313683:mee313683-math-0051. urn:x-wiley:2041210X:media:mee313683:mee313683-math-0052 are the lower and upper bounds for values that the trait urn:x-wiley:2041210X:media:mee313683:mee313683-math-0053 can have, which defines the domain over which the integration is performed. The integral urn:x-wiley:2041210X:media:mee313683:mee313683-math-0054 gives the total population size at time urn:x-wiley:2041210X:media:mee313683:mee313683-math-0055.
To make the model more biologically interpretable, the projection kernel urn:x-wiley:2041210X:media:mee313683:mee313683-math-0056 is usually split into sub-kernels (Equation 2). For example, a projection kernel to describe a life cycle where individuals can survive, transition to different state values, and reproduce via sexual and asexual pathways, can be split as follows.
where urn:x-wiley:2041210X:media:mee313683:mee313683-math-0058 is a sub-kernel describing transitions due to survival and trait changes of existing individuals, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0059 is a sub-kernel describing per-capita sexual contributions of existing individuals to recruitment and urn:x-wiley:2041210X:media:mee313683:mee313683-math-0060 is a sub-kernel describing per-capita asexual contributions of existing individuals to recruitment. The sub-kernels are typically comprised of functions derived from regression models that relate an individual's trait value urn:x-wiley:2041210X:media:mee313683:mee313683-math-0061 at time urn:x-wiley:2041210X:media:mee313683:mee313683-math-0062 to a new trait value urn:x-wiley:2041210X:media:mee313683:mee313683-math-0063 at urn:x-wiley:2041210X:media:mee313683:mee313683-math-0064. For example, the urn:x-wiley:2041210X:media:mee313683:mee313683-math-0065 kernel for Soay sheep Ovis aries on St. Kilda (Equation 3) may contain two regression models: (a) a logistic regression of survival on log body mass (Equation 4) and (b) a linear regression of log body mass at urn:x-wiley:2041210X:media:mee313683:mee313683-math-0066 on log body mass at urn:x-wiley:2041210X:media:mee313683:mee313683-math-0067 (Equations 5-6). In this example, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0068 is a normal probability density function with urn:x-wiley:2041210X:media:mee313683:mee313683-math-0069 given by the linear predictor of the mean, and with urn:x-wiley:2041210X:media:mee313683:mee313683-math-0070 computed from the standard deviation of the residuals from the linear regression model.
Analytical solutions to the integral in Equation 1 are usually not possible (Ellner & Rees, 2006). However, numerical approximations of these integrals can be constructed using a numerical integration rule. A commonly used rule is the midpoint rule (more complicated and precise methods are possible and will be implemented, though are not yet, see Ellner et al., 2016, Chapter 6). The midpoint rule divides the domain urn:x-wiley:2041210X:media:mee313683:mee313683-math-0075 into urn:x-wiley:2041210X:media:mee313683:mee313683-math-0076 artifical size bins centered at urn:x-wiley:2041210X:media:mee313683:mee313683-math-0077 with width urn:x-wiley:2041210X:media:mee313683:mee313683-math-0078. The midpoints urn:x-wiley:2041210X:media:mee313683:mee313683-math-0079 for urn:x-wiley:2041210X:media:mee313683:mee313683-math-0080. The midpoint rule approximation for Equation 1 then becomes:
In practice, the numerical approximation of the integral converts the continuous projection kernel into a (large) discretized matrix. A matrix multiplication of the discretized projection kernel and the discretized trait distribution then generates a new trait distribution, a process referred to as model iteration (sensu Easterling et al., 2000).

Equations 1 and 2 are an example of a simple IPM. A critical aspect of ipmr's functionality is the distinction between simple IPMs and general IPMs. A simple IPM incorporates a single continuous state variable. Equations 1 and 2 represent a simple IPM because there is only one continuous state, urn:x-wiley:2041210X:media:mee313683:mee313683-math-0082, and no additional discrete states. A general IPM models one or more continuous state variables, and/or discrete states. General IPMs are useful for modelling species with more complex life cycles. Many species’ life cycles contain multiple life stages that are not readily described by a single state variable. Similarly, individuals with similar trait values may behave differently depending on environmental context. For example, Bruno et al. (2011) modelled aspergillosis impacts on sea fan coral Gorgonia ventalina population dynamics by creating a model where colonies were cross classified by tissue area (continuously distributed) and infection status (a discrete state with two levels—infected and uninfected). Coulson et al. (2010) constructed a model for Soay sheep where the population was structured by body weight (continuously distributed) and age (discrete state). Mixtures of multiple continuous and discrete states are also possible. Indeed, the vital rates of many species with complex life cycles are often best described with multivariate state distributions (Caswell & Salguero-Gómez, 2013). A complete definition of the simple/general distinction is given in Ellner et al. (2016, Chapter 6).

2.1 A brief worked example of a simple IPM

Box 1 shows a brief example of how ipmr converts parameter estimates into an IPM. Perhaps the most frequently used metric derived from IPMs is the asymptotic per-capita population growth rate (urn:x-wiley:2041210X:media:mee313683:mee313683-math-0083, Caswell, 2001). When urn:x-wiley:2041210X:media:mee313683:mee313683-math-0084, the population is growing, while urn:x-wiley:2041210X:media:mee313683:mee313683-math-0085 indicates population decline. ipmr makes deriving estimates of urn:x-wiley:2041210X:media:mee313683:mee313683-math-0086 straightforward. Box 1 demonstrates how to parameterize a simple, deterministic IPM and estimate urn:x-wiley:2041210X:media:mee313683:mee313683-math-0087. The example uses a hypothetical species that can survive and grow, and reproduce sexually (but not asexually, so urn:x-wiley:2041210X:media:mee313683:mee313683-math-0088 in Equation 2). The population is structured by size, denoted urn:x-wiley:2041210X:media:mee313683:mee313683-math-0089 and urn:x-wiley:2041210X:media:mee313683:mee313683-math-0090, and there is no seedbank.

The urn:x-wiley:2041210X:media:mee313683:mee313683-math-0091 kernel is given by Equation 3, and the vital rates therein by Equations 4-6. The urn:x-wiley:2041210X:media:mee313683:mee313683-math-0092 kernel is given Equation 8:
Equation 9 is a recruit size distribution (where urn:x-wiley:2041210X:media:mee313683:mee313683-math-0096 denotes a normal probability density function), and Equation 10 describes the number of new recruits produced by plants as a function of size urn:x-wiley:2041210X:media:mee313683:mee313683-math-0097.

The code in Box 1 substitutes the actual probability density function (dnorm()) for urn:x-wiley:2041210X:media:mee313683:mee313683-math-0098 and urn:x-wiley:2041210X:media:mee313683:mee313683-math-0099, and uses inverse link functions instead of link functions. Otherwise, the math and the code should look quite similar.

2.2 Case study 1: A simple IPM

One use for IPMs is to evaluate potential performance and management of invasive species in their non-native range (e.g. Erickson et al., 2017). Calculating sensitivities and elasticities of urn:x-wiley:2041210X:media:mee313683:mee313683-math-0100 to kernel perturbations can help identify conservation management strategies (Baxter et al., 2006; Caswell, 2001; de Kroon et al., 1986; Ellner et al., 2016). Bogdan et al. (2021) constructed a simple IPM for a Carpobrotus species growing north of Tel Aviv, Israel. The model includes four regressions, and an estimated recruit size distribution. Table 1 provides the mathematical formulae, the corresponding R model formulae and the ipmr notation for each one. The case study materials also offer an alternative implementation that uses the generic predict() function to generate the same output. The final part of the case study provides examples of functions that compute kernel sensitivity and elasticity, the per-generation growth rate, and generation time for the model, as well as how to visualize these results.

2.3 Case study 2: A general age × size IPM

We use an age- and size-structured IPM from Ellner et al. (2016) to illustrate how to create general IPMs with ipmr. This case study demonstrates the suffix syntax for vital rate and kernel expressions, which is a key feature of ipmr (highlighted in bold in the ‘ipmr’ column in Table 2). The suffixes appended to each variable name in the ipmr formulation correspond to the subscript- and/or superscript used in the mathematical formulation. ipmr internally expands the model expressions and substitutes the range of ages and/or grouping variables in for the suffixes. This allows users to specify their model in a way that closely mirrors its mathematical notation, and saves users from the potentially error-prone process of re-typing model definitions many times or using for loops over the range of discrete states. The case study then demonstrates how to compute age-specific survival and fertility from the model outputs.


We have shown above how ipmr handles a variety of model implementations that go beyond the capabilities of existing scripts and packages. The underlying implementation based on metaprogramming should be able to readily incorporate future developments in parameterization methods. Regression modelling is a field that is constantly introducing new methods. As long as these new methods have functional forms for their expected value (or a function to compute them, such as predict()), ipmr should be able to implement IPMs using them.

Finally, one particularly useful aspect of the package is the proto_ipm data structure. The proto_ipm is the common data structure used to represent every model class in ipmr and provides a concise, standardized format for representing IPMs. Furthermore, the proto_ipm object is created without any raw data, only functional forms and parameters. We are in the process of creating the PADRINO IPM database using ipmr and proto_ipms as an ‘engine’ to re-build published IPMs using only functional forms and parameter estimates. This database could act as an IPM equivalent of the popular COMPADRE and COMADRE matrix population model databases (Salguero-Gómez et al., 2016; Salguero-Gómez et al., 2014). Recent work has highlighted the power of syntheses that harness many structured population models (Adler et al., 2014; Compagnoni et al., 2021; Salguero-Gómez et al., 2016). Despite the wide variety of models that are currently published in the IPM literature, ipmr's functional approach is able to reproduce nearly all of them without requiring any raw data at all.


We thank the Associate Editor and two anonymous reviewers for comments that greatly improved this manuscript.


    The authors declare no conflicts of interest.


    All authors contributed to package design. S.C.L. implemented the package. All authors wrote the first draft of the manuscript and contributed to revisions.


    The peer review history for this article is available at https://publons.com/publon/10.1111/2041-210X.13683.


    The Carpobrotus dataset is included in the ipmr R package. The package is available on GitHub at https://github.com/levisc8/ipmr, CRAN at https://cran.r-project.org/web/packages/ipmr/index.html (Levin et al., 2021), and Zenodo at https://doi.org/10.5281/zenodo.5095062 (Levin, 2021). The paper and case studies do not use any other data.