LTREs, sLTREs, and MPM import with Anthyllis vulneraria

Richard P. Shefferson and Raziel Davison

This document was built in Markdown in R 4.1.1 and compiled on 08 September 2021. It covers package lefko3 version 3.8.0. Please note that this vignette was written with space considerations in mind. To reduce output size, we have prevented some statements from running if they produce long stretches of output. Examples include most summary() calls. In these cases, we include hashtagged versions of these calls, and our text assumes that the user runs these statements without hashtags.

CASE STUDIES OF BELGIAN Anthyllis vulneraria POPULATIONS

In this vignette, we will import a MPM created elsewhere, edit it by adding, removing, and subsetting matrices, and analyze it via LTRE and sLTRE analysis. This is an ahistorical MPM, and so we do not include historical analyses in this vignette. Please see the other vignettes included in package lefko3, as well as further vignettes posted online on the projects page of the Shefferson lab website, for further demonstrations of raw MPMs, function-based MPMs, IPMs, and age-by-stage MPMs.

ORGANISM AND POPULATIONS

Davison et al. (2010) presented one of the first versions of the stochastic life table response experiment (sLTRE). They then used this method to report stochastic contributions made by differences in vital rate means and variances among nine natural populations of Anthyllis vulneraria, also known as kidney vetch, occurring in calcareous grasslands in the Viroin Valley of south-western Belgium. A. vulneraria is a grassland specialist and the unique host plant of the Red Book-listed blue butterfly (Cupido minimus). They also presented a deterministic life table response experiment (LTRE) for comparison of both theory and results. A. vulneraria is a short-lived, rosette-forming legume with a complex life cycle including stasis and retrogression between four stages but no seedbank (seedlings, juveniles, small adults and large adults; Fig. 9.1).

Figure 9.1. Life history model of Anthyllis vulneraria. Solid arrows indicate survival transitions while dashed arrows indicate fecundity transitions.

Ten populations (N = 27-50,000) growing in distinct grassland fragments were surveyed between 2003 and 2006, yielding three (4x4) annual transition matrices for each population. The populations occurred within grassland fragments, and were mostly managed as nature reserves through rotational sheep grazing. These surveys coincided with a summer heat wave (2003), followed by a spring drought (2005) and an even more extreme heat wave (2006). These populations have been subject to detailed study for aspects of their genetics and demography, and further details on the sites can be obtained through the resulting publications (Krauss, Steffan-Dewenter, and Tscharntke 2004; Honnay et al. 2006; Piessens et al. 2009).

OVERALL GOALS AND INITIAL CONSIDERATIONS

Our goal in this exercise will be to import the published MPMs available for these ten populations of Anthyllis vulneraria, show how the resulting lefkoMat objects can be edited, and analyze the demographic differences between populations using deterministic and stochastic life table response experiments (LTRE and sLTRE) of the nine of these populations that were analyzed in Davison et al. (2010). As we have the exact same matrices utilized in Davison et al. (2010), we will attempt to produce the exact same results as in that paper.

We begin by clearing memory and loading package lefko3.

rm(list=ls(all=TRUE))
library(lefko3)

Step 1. Life history model development

We will first need to describe the life history characterizing the dataset, matching it to our analyses properly with a stageframe. Since we do not have the original demographic dataset that produced the published matrices, and we do not need to estimate any size-based vital rates, we do not need to know the exact sizes of plants and so will use only proxy values. Other characteristics must be exact, however, to make sure that the analyses work properly. This includes all other stage descriptions, including reproductive status, propagule status, etc.

sizevector <- c(1, 1, 2, 3) # These sizes are not from the original paper
stagevector <- c("Sdl", "Veg", "SmFlo", "LFlo")
repvector <- c(0, 0, 1, 1)
obsvector <- c(1, 1, 1, 1)
matvector <- c(0, 1, 1, 1)
immvector <- c(1, 0, 0, 0)
propvector <- c(1, 0, 0, 0)
indataset <- c(1, 1, 1, 1)
binvec <- c(0.5, 0.5, 0.5, 0.5)
comments <- c("Seedling", "Vegetative adult", "Small flowering",
  "Large flowering")

anthframe <- sf_create(sizes = sizevector, stagenames = stagevector,
  repstatus = repvector, obsstatus = obsvector, matstatus = matvector,
  immstatus = immvector, indataset = indataset, binhalfwidth = binvec,
  propstatus = propvector, comments = comments)
anthframe
#>   stage size repstatus obsstatus propstatus immstatus matstatus indataset
#> 1   Sdl    1         0         1          1         1         0         1
#> 2   Veg    1         0         1          0         0         1         1
#> 3 SmFlo    2         1         1          0         0         1         1
#> 4  LFlo    3         1         1          0         0         1         1
#>   binhalfwidth_raw min_age max_age sizebin_min sizebin_max sizebin_center
#> 1              0.5      NA      NA         0.5         1.5              1
#> 2              0.5      NA      NA         0.5         1.5              1
#> 3              0.5      NA      NA         1.5         2.5              2
#> 4              0.5      NA      NA         2.5         3.5              3
#>   sizebin_width         comments
#> 1             1         Seedling
#> 2             1 Vegetative adult
#> 3             1  Small flowering
#> 4             1  Large flowering

Notice that this object implies that there is no seedbank - A. vulneraria is not capable of seed dormancy. If seed dormancy were possible, then we would need to include a dormant seed stage as an alternative propagule stage, yielding 5 total stages. Currently, the only propagule stage is the seedling stage, which is treated as a seedling because the transition to seedling involves the dispersal of the seed followed by germination itself.

Step 2. Data organization

Next we will enter the data for this vignette. Our data is in the form of matrices published in Davison et al. (2010). We will enter these matrices as standard R matrix class objects. All matrices are 4 rows by 4 columns big, and note that we fill them by row. As an example, let’s load the first matrix and take a look at it.

# POPN C 2003-2004
XC3 <- matrix(c(0, 0, 1.74, 1.74,
  0.208333333, 0, 0, 0.057142857,
  0.041666667, 0.076923077, 0, 0,
  0.083333333, 0.076923077, 0.066666667, 0.028571429), 4, 4, byrow = TRUE)
XC3
#>            [,1]       [,2]       [,3]       [,4]
#> [1,] 0.00000000 0.00000000 1.74000000 1.74000000
#> [2,] 0.20833333 0.00000000 0.00000000 0.05714286
#> [3,] 0.04166667 0.07692308 0.00000000 0.00000000
#> [4,] 0.08333333 0.07692308 0.06666667 0.02857143

These are A matrices, meaning that they include all survival-transitions and fecundity rates for the population as a whole. The corresponding U and F matrices were not provided in that paper. However, these matrices are simple enough and utilize a simple enough life history model that we can infer the associated U and F matrices. Here, there is no survival-transition between the two reproductive adult stages (SmFlo and LFlo) to the seedling stage (Sdl), so the elements valued at 1.74 in the top right-hand corner must be composed purely of fecundity values. The rest of the matrix must be composed of survival-transition probabilities, as the life history model suggests that there are not other fecundity transitions. The order of rows and columns corresponds to the order of stages in the stageframe anthframe. This structure will be very useful for us in having R determine the correct U and F matrices for us.

One further note relates to the order of entry of elements. Close inspection of the input and output shows that the elements are input by row, and that the byrow = TRUE option is set. This is because the published matrices were supplied as MATLAB code, and MATLAB uses row-by-row matrix input, while R uses older (and more fundamental) computer convention and defaults to matrix element entry by column. Leaving the byrow = TRUE option out will lead to the transpose matrices being input, and this would result in the wrong inferences.

Let’s now load most of the remaining matrices. We will load all of them except for those corresponding to the last population.

# POPN C 2004-2005
XC4 <- matrix(c(0, 0, 0.3, 0.6,
0.32183908, 0.142857143, 0, 0,
0.16091954, 0.285714286, 0, 0,
0.252873563, 0.285714286, 0.5, 0.6), 4, 4, byrow = TRUE)

# POPN C 2005-2006
XC5 <- matrix(c(0, 0, 0.50625, 0.675,
0, 0, 0, 0.035714286,
0.1, 0.068965517, 0.0625, 0.107142857,
0.3, 0.137931034, 0, 0.071428571), 4, 4, byrow = TRUE)

# POPN E 2003-2004
XE3 <- matrix(c(0, 0, 2.44, 6.569230769,
0.196428571, 0, 0, 0,
0.125, 0.5, 0, 0,
0.160714286, 0.5, 0.133333333, 0.076923077), 4, 4, byrow = TRUE)

# POPN E 2004-2005
XE4 <- matrix(c(0, 0, 0.45, 0.646153846,
0.06557377, 0.090909091, 0.125, 0,
0.032786885, 0, 0.125, 0.076923077,
0.049180328, 0, 0.125, 0.230769231), 4, 4, byrow = TRUE)

# POPN E 2005-2006
XE5 <- matrix(c(0, 0, 2.85, 3.99,
0.083333333, 0, 0, 0,
0, 0, 0, 0,
0.416666667, 0.1, 0, 0.1), 4, 4, byrow = TRUE)

# POPN F 2003-2004
XF3 <- matrix(c(0, 0, 1.815, 7.058333333,
0.075949367, 0, 0.05, 0.083333333,
0.139240506, 0, 0, 0.25,
0.075949367, 0, 0, 0.083333333), 4, 4, byrow = TRUE)

# POPN F 2004-2005
XF4 <- matrix(c(0, 0, 1.233333333, 7.4,
0.223880597, 0, 0.111111111, 0.142857143,
0.134328358, 0.272727273, 0.166666667, 0.142857143,
0.119402985, 0.363636364, 0.055555556, 0.142857143), 4, 4, byrow = TRUE)

# POPN F 2005-2006
XF5 <- matrix(c(0, 0, 1.06, 3.372727273,
0.073170732, 0.025, 0.033333333, 0,
0.036585366, 0.15, 0.1, 0.136363636,
0.06097561, 0.225, 0.166666667, 0.272727273), 4, 4, byrow = TRUE)

# POPN G 2003-2004
XG3 <- matrix(c(0, 0, 0.245454545, 2.1,
0, 0, 0.045454545, 0,
0.125, 0, 0.090909091, 0,
0.125, 0, 0.090909091, 0.333333333), 4, 4, byrow = TRUE)

# POPN G 2004-2005
XG4 <- matrix(c(0, 0, 1.1, 1.54,
0.111111111, 0, 0, 0,
0, 0, 0, 0,
0.111111111, 0, 0, 0), 4, 4, byrow = TRUE)

# POPN G 2005-2006
XG5 <- matrix(c(0, 0, 0, 1.5,
0, 0, 0, 0,
0.090909091, 0, 0, 0,
0.545454545, 0.5, 0, 0.5), 4, 4, byrow = TRUE)

# POPN H (EXCLDED FROM ANALYSIS B/C OF UNREALISTIC ELASTICITIES)
XH3 <- matrix(c(0, 0, 0.1125, 1.05,
0.2, 0, 0, 0,
0, 0.5, 0, 0,
0.2, 0.5, 0, 0), 4, 4, byrow = TRUE)

XH4 <- matrix(c(0, 0, 0, 0,
0, 0, 0.5, 0,
0.8, 0.5, 0.25, 0.25,
0.2, 0, 0, 0.75), 4, 4, byrow = TRUE)

XH5 <- matrix(c(0, 0, 0.2, 1.05,
0, 0, 0, 0,
0.001, 0.001, 0.333333333, 0, #ELEMENTS (3,1),(4,1),(3,2) REPLACED W NONZERO
0.001, 0, 0, 0), 4, 4, byrow = TRUE)

# POPN L 2003-2004
XL3 <- matrix(c(0, 0, 1.785365854, 1.856521739,
0.128571429, 0, 0, 0.010869565,
0.028571429, 0, 0, 0,
0.014285714, 0, 0, 0.02173913), 4, 4, byrow = TRUE)

# POPN L 2004-2005
XL4 <- matrix(c(0, 0, 14.25, 16.625,
0.131443299, 0.057142857, 0, 0.25,
0.144329897, 0, 0, 0,
0.092783505, 0.2, 0, 0.25), 4, 4, byrow = TRUE)

# POPN L 2005-2006
XL5 <- matrix(c(0, 0, 0.594642857, 1.765909091,
0, 0, 0.017857143, 0,
0.021052632, 0.018518519, 0.035714286, 0.045454545,
0.021052632, 0.018518519, 0.035714286, 0.068181818), 4, 4, byrow = TRUE)

# POPN O 2003-2004
XO3 <- matrix(c(0, 0, 11.5, 2.775862069,
0.6, 0.285714286, 0.333333333, 0.24137931,
0.04, 0.142857143, 0, 0,
0.16, 0.285714286, 0, 0.172413793), 4, 4, byrow = TRUE)

# POPN O 2004-2005
XO4 <- matrix(c(0, 0, 3.78, 1.225,
0.28358209, 0.171052632, 0, 0.166666667,
0.084577114, 0.026315789, 0, 0.055555556,
0.139303483, 0.447368421, 0, 0.305555556), 4, 4, byrow = TRUE)

# POPN O 2005-2006
XO5 <- matrix(c(0, 0, 1.542857143, 1.035616438,
0.126984127, 0.105263158, 0.047619048, 0.054794521,
0.095238095, 0.157894737, 0.19047619, 0.082191781,
0.111111111, 0.223684211, 0, 0.356164384), 4, 4, byrow = TRUE)

# POPN Q 2003-2004
XQ3 <- matrix(c(0, 0, 0.15, 0.175,
0, 0, 0, 0,
0, 0, 0, 0,
1, 0, 0, 0), 4, 4, byrow = TRUE)

# POPN Q 2004-2005
XQ4 <- matrix(c(0, 0, 0, 0.25,
0, 0, 0, 0,
0, 0, 0, 0,
1, 0.666666667, 0, 1), 4, 4, byrow = TRUE)

# POPN Q 2005-2006
XQ5 <- matrix(c(0, 0, 0, 1.428571429,
0, 0, 0, 0.142857143,
0.25, 0, 0, 0,
0.25, 0, 0, 0.571428571), 4, 4, byrow = TRUE)

# POPN R 2003-2004
XR3 <- matrix(c(0, 0, 0.7, 0.6125,
0.25, 0, 0, 0.125,
0, 0, 0, 0,
0.25, 0.166666667, 0, 0.25), 4, 4, byrow = TRUE)

# POPN R 2004-2005
XR4 <- matrix(c(0, 0, 0, 0.6,
0.285714286, 0, 0, 0,
0.285714286, 0.333333333, 0, 0,
0.285714286, 0.333333333, 0, 1), 4, 4, byrow = TRUE)

# POPN R 2005-2006
XR5 <- matrix(c(0, 0, 0.7, 0.6125,
0, 0, 0, 0,
0, 0, 0, 0,
0.333333333, 0, 0.333333333, 0.625), 4, 4, byrow = TRUE)

We need to incorporate all of these matrices into a lefkoMat object. The next step to accomplish this goal is to organize the matrices in the proper order within a list. The next lines will do that. Feel free to remove the hashtag to see what the object looks like.

mats_list <- list(XC3, XC4, XC5, XE3, XE4, XE5, XF3, XF4, XF5, XG3, XG4, XG5,
  XH3, XH4, XH5, XL3, XL4, XL5, XO3, XO4, XO5, XQ3, XQ4, XQ5, XR3, XR4, XR5)
#mats_list

Finally we come to the creation of the lefkoMat object to hold these matrices. We do this by calling the create_lM() function with the list object mats_list, which we have just created. We also include metadata describing the order of populations (here treated as patches) and the order of monitoring occasions. Run the following lines, removing the hashtag to see what the object looks like.

pch_ord <- c("C", "C", "C", "E", "E", "E", "F", "F", "F", "G", "G", "G", "H",
  "H", "H", "L", "L", "L", "O", "O", "O", "Q", "Q", "Q", "R", "R", "R")
yr_ord <- c(2003, 2004, 2005, 2003, 2004, 2005, 2003, 2004, 2005, 2003, 2004,
  2005, 2003, 2004, 2005, 2003, 2004, 2005, 2003, 2004, 2005, 2003, 2004, 2005,
  2003, 2004, 2005)

anth_lM1 <- create_lM(mats_list, anthframe, historical = FALSE, poporder = 1,
  patchorder = pch_ord, yearorder = yr_ord)
#anth_lM1

The resulting object has all of the elements of a standard lefkoMat object except for elements related to quality control in the demographic dataset and linear modeling. The option UFdecomp was left at its default (UFdecomp = TRUE), and so create_lM() used the stageframe to infer where fecundity values were located in the matrices and created U and F matrices separating those values. The default settings for historical and agebystage are FALSE, yielding NA values in place of the hstages and agestages elements, respectively. In this case, setting either of those to TRUE would have led to errors.

Let’s now take a look at a summary of our new lefkoMat object.

summary(anth_lM1)
#> 
#> This ahistorical lefkoMat object contains 27 matrices.
#> 
#> Each matrix is a square matrix with 4 rows and columns, and a total of 16 elements.
#> A total of 172 survival transitions were estimated, with 6.37 per matrix.
#> A total of 48 fecundity transitions were estimated, with 1.778 per matrix.
#> 
#> Survival probability sum check (each matrix represented by column in order):
#>           [,1]  [,2]   [,3]   [,4]   [,5]  [,6]   [,7]  [,8]  [,9] [,10]  [,11]
#> Min.    0.0667 0.500 0.0625 0.0769 0.0909 0.000 0.0000 0.333 0.171 0.000 0.0000
#> 1st Qu. 0.0810 0.575 0.1708 0.1192 0.1334 0.075 0.0375 0.405 0.268 0.170 0.0000
#> Median  0.1198 0.657 0.2106 0.3077 0.2276 0.100 0.1706 0.453 0.350 0.239 0.0000
#> Mean    0.1599 0.637 0.2209 0.4231 0.2303 0.175 0.1895 0.469 0.320 0.203 0.0556
#> 3rd Qu. 0.1987 0.720 0.2607 0.6116 0.3245 0.200 0.3225 0.517 0.402 0.271 0.0556
#> Max.    0.3333 0.736 0.4000 1.0000 0.3750 0.500 0.4167 0.636 0.409 0.333 0.2222
#>         [,12] [,13] [,14]   [,15]  [,16] [,17]  [,18] [,19] [,20] [,21] [,22]
#> Min.    0.000  0.00 0.500 0.00000 0.0000 0.000 0.0370 0.333 0.000 0.238  0.00
#> 1st Qu. 0.375  0.00 0.688 0.00075 0.0000 0.193 0.0408 0.394 0.381 0.310  0.00
#> Median  0.500  0.20 0.875 0.00150 0.0163 0.313 0.0657 0.564 0.518 0.410  0.00
#> Mean    0.409  0.35 0.812 0.08408 0.0510 0.281 0.0705 0.565 0.420 0.388  0.25
#> 3rd Qu. 0.534  0.55 1.000 0.08483 0.0673 0.401 0.0954 0.736 0.557 0.488  0.25
#> Max.    0.636  1.00 1.000 0.33333 0.1714 0.500 0.1136 0.800 0.645 0.493  1.00
#>         [,23] [,24] [,25] [,26] [,27]
#> Min.    0.000 0.000 0.000 0.000 0.000
#> 1st Qu. 0.500 0.000 0.125 0.500 0.250
#> Median  0.833 0.250 0.271 0.762 0.333
#> Mean    0.667 0.304 0.260 0.631 0.323
#> 3rd Qu. 1.000 0.554 0.406 0.893 0.406
#> Max.    1.000 0.714 0.500 1.000 0.625
#> NULL

So we see that we have input 27 matrices, with 3 per patch and 9 patches (representative of populations). Each matrix has 16 elements, and roughly 8 are non-zero in each case.

Now let’s imagine that we forgot to incorporate matrices from a population, and wish to add them to our lefkoMat object. It turns out that this is true, because we have not yet supplied the matrices for population S. We can incorporate these new matrices into this lefkoMat object using the add_lM() function.

# POPN S 2003-2004
XS3 <- matrix(c(0, 0, 2.1, 0.816666667,
0.166666667, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0.166666667), 4, 4, byrow = TRUE)

# POPN S 2004-2005
XS4 <- matrix(c(0, 0, 0, 7,
0.333333333, 0.5, 0, 0,
0, 0, 0, 0,
0.333333333, 0, 0, 1), 4, 4, byrow = TRUE)

# POPN S 2005-2006
XS5 <- matrix(c(0, 0, 0, 1.4,
0, 0, 0, 0,
0, 0, 0, 0.2,
0.111111111, 0.75, 0, 0.2), 4, 4, byrow = TRUE)

anth_lM2 <- add_lM(anth_lM1, Amats = list(XS3, XS4, XS5), UFdecomp = TRUE,
  patch = "S", year = c(2003, 2004, 2005))

summary(anth_lM2)
#> 
#> This ahistorical lefkoMat object contains 30 matrices.
#> 
#> Each matrix is a square matrix with 4 rows and columns, and a total of 16 elements.
#> A total of 172 survival transitions were estimated, with 5.733 per matrix.
#> A total of 48 fecundity transitions were estimated, with 1.6 per matrix.
#> 
#> Survival probability sum check (each matrix represented by column in order):
#>           [,1]  [,2]   [,3]   [,4]   [,5]  [,6]   [,7]  [,8]  [,9] [,10]  [,11]
#> Min.    0.0667 0.500 0.0625 0.0769 0.0909 0.000 0.0000 0.333 0.171 0.000 0.0000
#> 1st Qu. 0.0810 0.575 0.1708 0.1192 0.1334 0.075 0.0375 0.405 0.268 0.170 0.0000
#> Median  0.1198 0.657 0.2106 0.3077 0.2276 0.100 0.1706 0.453 0.350 0.239 0.0000
#> Mean    0.1599 0.637 0.2209 0.4231 0.2303 0.175 0.1895 0.469 0.320 0.203 0.0556
#> 3rd Qu. 0.1987 0.720 0.2607 0.6116 0.3245 0.200 0.3225 0.517 0.402 0.271 0.0556
#> Max.    0.3333 0.736 0.4000 1.0000 0.3750 0.500 0.4167 0.636 0.409 0.333 0.2222
#>         [,12] [,13] [,14]   [,15]  [,16] [,17]  [,18] [,19] [,20] [,21] [,22]
#> Min.    0.000  0.00 0.500 0.00000 0.0000 0.000 0.0370 0.333 0.000 0.238  0.00
#> 1st Qu. 0.375  0.00 0.688 0.00075 0.0000 0.193 0.0408 0.394 0.381 0.310  0.00
#> Median  0.500  0.20 0.875 0.00150 0.0163 0.313 0.0657 0.564 0.518 0.410  0.00
#> Mean    0.409  0.35 0.812 0.08408 0.0510 0.281 0.0705 0.565 0.420 0.388  0.25
#> 3rd Qu. 0.534  0.55 1.000 0.08483 0.0673 0.401 0.0954 0.736 0.557 0.488  0.25
#> Max.    0.636  1.00 1.000 0.33333 0.1714 0.500 0.1136 0.800 0.645 0.493  1.00
#>         [,23] [,24] [,25] [,26] [,27]  [,28] [,29]  [,30]
#> Min.    0.000 0.000 0.000 0.000 0.000 0.0000 0.000 0.0000
#> 1st Qu. 0.500 0.000 0.125 0.500 0.250 0.0000 0.375 0.0833
#> Median  0.833 0.250 0.271 0.762 0.333 0.0833 0.583 0.2556
#> Mean    0.667 0.304 0.260 0.631 0.323 0.0833 0.542 0.3153
#> 3rd Qu. 1.000 0.554 0.406 0.893 0.406 0.1667 0.750 0.4875
#> Max.    1.000 0.714 0.500 1.000 0.625 0.1667 1.000 0.7500
#> NULL

So here we see that we now have 30 matrices, the correct number given that we added 3 matrices to our main lefkoMat object, which contained 27 originally. We can see the labels element to take a peek at the order.

anth_lM2$labels
#>    pop patch year2
#> 1    1     C  2003
#> 2    1     C  2004
#> 3    1     C  2005
#> 4    1     E  2003
#> 5    1     E  2004
#> 6    1     E  2005
#> 7    1     F  2003
#> 8    1     F  2004
#> 9    1     F  2005
#> 10   1     G  2003
#> 11   1     G  2004
#> 12   1     G  2005
#> 13   1     H  2003
#> 14   1     H  2004
#> 15   1     H  2005
#> 16   1     L  2003
#> 17   1     L  2004
#> 18   1     L  2005
#> 19   1     O  2003
#> 20   1     O  2004
#> 21   1     O  2005
#> 22   1     Q  2003
#> 23   1     Q  2004
#> 24   1     Q  2005
#> 25   1     R  2003
#> 26   1     R  2004
#> 27   1     R  2005
#> 28   1     S  2003
#> 29   1     S  2004
#> 30   1     S  2005

Now let’s introduce two more functions. First of all, let’s say that we were interested in creating a new lefkoMat object that was a subset of the original. For example, let’s say that we wanted one object that held just matrices for population S, and another object that held just matrices for the year 2004. We can do this with the function subset_lM(), as below.

anth_lM3 <- subset_lM(anth_lM2, patch = "S")
anth_lM4 <- subset_lM(anth_lM2, year = 2004)

summary(anth_lM3)
#> 
#> This ahistorical lefkoMat object contains 3 matrices.
#> 
#> Each matrix is a square matrix with 4 rows and columns, and a total of 16 elements.
#> A total of 172 survival transitions were estimated, with 57.333 per matrix.
#> A total of 48 fecundity transitions were estimated, with 16 per matrix.
#> 
#> Survival probability sum check (each matrix represented by column in order):
#>           [,1]  [,2]   [,3]
#> Min.    0.0000 0.000 0.0000
#> 1st Qu. 0.0000 0.375 0.0833
#> Median  0.0833 0.583 0.2556
#> Mean    0.0833 0.542 0.3153
#> 3rd Qu. 0.1667 0.750 0.4875
#> Max.    0.1667 1.000 0.7500
#> NULL
summary(anth_lM4)
#> 
#> This ahistorical lefkoMat object contains 10 matrices.
#> 
#> Each matrix is a square matrix with 4 rows and columns, and a total of 16 elements.
#> A total of 172 survival transitions were estimated, with 17.2 per matrix.
#> A total of 48 fecundity transitions were estimated, with 4.8 per matrix.
#> 
#> Survival probability sum check (each matrix represented by column in order):
#>          [,1]   [,2]  [,3]   [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
#> Min.    0.500 0.0909 0.333 0.0000 0.500 0.000 0.000 0.000 0.000 0.000
#> 1st Qu. 0.575 0.1334 0.405 0.0000 0.688 0.193 0.381 0.500 0.500 0.375
#> Median  0.657 0.2276 0.453 0.0000 0.875 0.313 0.518 0.833 0.762 0.583
#> Mean    0.637 0.2303 0.469 0.0556 0.812 0.281 0.420 0.667 0.631 0.542
#> 3rd Qu. 0.720 0.3245 0.517 0.0556 1.000 0.401 0.557 1.000 0.893 0.750
#> Max.    0.736 0.3750 0.636 0.2222 1.000 0.500 0.645 1.000 1.000 1.000
#> NULL

Everything worked as expected. The final function is the delete_lM() function, which will delete matrices from an object. We will create a new lefkoMat object that deletes population H, since that population’s data was not used in the analysis shown in Davison et al. (2010). This last lefkoMat object will be our main target for analysis in the rest of this vignette.

anth_finallM <- delete_lM(anth_lM2, patch = "H")
summary(anth_finallM)
#> 
#> This ahistorical lefkoMat object contains 27 matrices.
#> 
#> Each matrix is a square matrix with 4 rows and columns, and a total of 16 elements.
#> A total of 172 survival transitions were estimated, with 6.37 per matrix.
#> A total of 48 fecundity transitions were estimated, with 1.778 per matrix.
#> 
#> Survival probability sum check (each matrix represented by column in order):
#>           [,1]  [,2]   [,3]   [,4]   [,5]  [,6]   [,7]  [,8]  [,9] [,10]  [,11]
#> Min.    0.0667 0.500 0.0625 0.0769 0.0909 0.000 0.0000 0.333 0.171 0.000 0.0000
#> 1st Qu. 0.0810 0.575 0.1708 0.1192 0.1334 0.075 0.0375 0.405 0.268 0.170 0.0000
#> Median  0.1198 0.657 0.2106 0.3077 0.2276 0.100 0.1706 0.453 0.350 0.239 0.0000
#> Mean    0.1599 0.637 0.2209 0.4231 0.2303 0.175 0.1895 0.469 0.320 0.203 0.0556
#> 3rd Qu. 0.1987 0.720 0.2607 0.6116 0.3245 0.200 0.3225 0.517 0.402 0.271 0.0556
#> Max.    0.3333 0.736 0.4000 1.0000 0.3750 0.500 0.4167 0.636 0.409 0.333 0.2222
#>         [,12]  [,13] [,14]  [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22]
#> Min.    0.000 0.0000 0.000 0.0370 0.333 0.000 0.238  0.00 0.000 0.000 0.000
#> 1st Qu. 0.375 0.0000 0.193 0.0408 0.394 0.381 0.310  0.00 0.500 0.000 0.125
#> Median  0.500 0.0163 0.313 0.0657 0.564 0.518 0.410  0.00 0.833 0.250 0.271
#> Mean    0.409 0.0510 0.281 0.0705 0.565 0.420 0.388  0.25 0.667 0.304 0.260
#> 3rd Qu. 0.534 0.0673 0.401 0.0954 0.736 0.557 0.488  0.25 1.000 0.554 0.406
#> Max.    0.636 0.1714 0.500 0.1136 0.800 0.645 0.493  1.00 1.000 0.714 0.500
#>         [,23] [,24]  [,25] [,26]  [,27]
#> Min.    0.000 0.000 0.0000 0.000 0.0000
#> 1st Qu. 0.500 0.250 0.0000 0.375 0.0833
#> Median  0.762 0.333 0.0833 0.583 0.2556
#> Mean    0.631 0.323 0.0833 0.542 0.3153
#> 3rd Qu. 0.893 0.406 0.1667 0.750 0.4875
#> Max.    1.000 0.625 0.1667 1.000 0.7500
#> NULL

So far so good, but let’s also take a peek at the labels element to make sure.

anth_finallM$labels
#>    pop patch year2
#> 1    1     C  2003
#> 2    1     C  2004
#> 3    1     C  2005
#> 4    1     E  2003
#> 5    1     E  2004
#> 6    1     E  2005
#> 7    1     F  2003
#> 8    1     F  2004
#> 9    1     F  2005
#> 10   1     G  2003
#> 11   1     G  2004
#> 12   1     G  2005
#> 13   1     L  2003
#> 14   1     L  2004
#> 15   1     L  2005
#> 16   1     O  2003
#> 17   1     O  2004
#> 18   1     O  2005
#> 19   1     Q  2003
#> 20   1     Q  2004
#> 21   1     Q  2005
#> 22   1     R  2003
#> 23   1     R  2004
#> 24   1     R  2005
#> 25   1     S  2003
#> 26   1     S  2004
#> 27   1     S  2005

All looks fine! Let’s now skip the tests of history and vital rate modeling, since that cannot be performed without the original demographic dataset. We will also skip MPM estimation, since we already have our MPM.

Step 3. Tests of history, and vital rate modeling - SKIPPED!

Step 4. MPM estimation - SKIPPED!

Step 5. MPM analysis

First, we will develop an arithmetic mean matrix, and then we will assess the population growth rate. We will assess both the annual deterministic \(\lambda\), as well as stochastic \(\lambda\) (note that the stochastic growth rate is generally given in logarithmic terms - we will take its natural exponent to make it comparable to \(\lambda\)).

anth_lmean <- lmean(anth_finallM)

lambda2 <- lambda3(anth_finallM)
lambda2m <- lambda3(anth_lmean)
set.seed(42)
sl2 <- slambda3(anth_finallM) #Stochastic growth rate
sl2$expa <- exp(sl2$a)

plot(lambda ~ year2, data = subset(lambda2, patch == "C"), ylim = c(0, 2.5),xlab = "Year",
  ylab = expression(lambda), type = "l", col = "gray", lty= 2, lwd = 2, bty = "n")
lines(lambda ~ year2, data = subset(lambda2, patch == "E"), col = "gray", lty= 2, lwd = 2)
lines(lambda ~ year2, data = subset(lambda2, patch == "F"), col = "gray", lty= 2, lwd = 2)
lines(lambda ~ year2, data = subset(lambda2, patch == "G"), col = "gray", lty= 2, lwd = 2)
lines(lambda ~ year2, data = subset(lambda2, patch == "L"), col = "gray", lty= 2, lwd = 2)
lines(lambda ~ year2, data = subset(lambda2, patch == "O"), col = "gray", lty= 2, lwd = 2)
lines(lambda ~ year2, data = subset(lambda2, patch == "Q"), col = "gray", lty= 2, lwd = 2)
lines(lambda ~ year2, data = subset(lambda2, patch == "R"), col = "gray", lty= 2, lwd = 2)
lines(lambda ~ year2, data = subset(lambda2, patch == "S"), col = "gray", lty= 2, lwd = 2)
abline(a = lambda2m$lambda[1], b = 0, lty = 1, lwd = 4, col = "orangered")
abline(a = sl2$expa[1], b = 0, lty = 1, lwd = 4, col = "darkred")
legend("topleft", c("det annual", "det mean", "stochastic"), lty = c(2, 1, 1),
  col = c("gray", "orangered", "darkred"), lwd = c(2, 4, 4), bty = "n")

Figure 9.2. Deterministic vs. stochastic lambda

Very clearly, these populations exhibit extremely variable growth across the short interval of time that they were monitored. Also very clear is that they appear to be on the decline, as shown by \(\lambda\) for the overall mean matrix, and the stochastic growth rate.

At this point, let’s conduct a life table response experiment (LTRE). This will be a deterministic LTRE, meaning that we will assess the impacts of differences in matrix elements between the core matrices input via the lefkoMat object anth_finallM and the overall arithmetic grand mean matrix. Note that we could use a different reference matrix if we wished, but the default if refmats = NA is to use the arithmetic grand mean. Please remove the hashtag from the end line of the next block to see the resulting output.

trialltre_det <- ltre3(anth_finallM, refmats = NA, stochastic = FALSE,
  steps = 10000, time_weights = NA, sparse = "auto")
#> Warning: Matrices input as mats will also be used as reference matrices.
#> Using all refmats matrices as reference matrices.
#trialltre_det

The resulting lefkoLTRE object gives the LTRE contributions for each matrix, including the annual matrices. While the differences in LTRE contributions across space are of interest, we cannot really infer differences across time this way because matrices are not related additively across time. To assess the contributions across space while accounting for temporal change, we should conduct a stochastic LTRE (sLTRE), as below.

trialltre_sto <- ltre3(anth_finallM, refmats = NA, stochastic = TRUE,
  steps = 10000, time_weights = NA, sparse = "auto")
#> Warning: Matrices input as mats will also be used as reference matrices.
#> Using all refmats matrices as reference matrices.
#trialltre_sto

The sLTRE produces output that is a bit different from the deterministic LTRE output. In the output, we see two lists of matrices prior to the MPM metadata. The first, ltre_mean, is a list of matrices showing the impact on the stochastic population growth rate of differences in mean elements between the patch-level temporal mean matrices and the reference temporal mean matrix. The second, ltre_sd, is a list of matrices showing the impact on the stochastic population growth rate of differences in the temporal standard deviation of each element between the patch-level and reference matrix sets. In other words, while a standard LTRE shows the impact of changes in matrix elements on \(\lambda\), the sLTRE shows the impacts of changes in the temporal mean and variability of matrix elements on \(\text{log} \lambda\). The labels element shows the order of matrices with reference to the populations or patches (remember that here, the populations are referred to as patches).

The output objects are large and can take a great deal of effort to look over and understand. Therefore, we will show three approaches to assessing these objects, using an approach similar to that used to assess elasticities. These methods can be used to assess patterns in all 9 populations, but for brevity we will focus only on the first population here. First, we will identify the elements most strongly impacting the population growth rate in each case.

writeLines("The greatest (i.e most positive) deterministic LTRE contribution: ")
#> The greatest (i.e most positive) deterministic LTRE contribution:
max(trialltre_det$ltre_det[[1]])
#> [1] 0.02403949
writeLines("The greatest deterministic LTRE contribution is associated with element: ")
#> The greatest deterministic LTRE contribution is associated with element:
which(trialltre_det$ltre_det[[1]] == max(trialltre_det$ltre_det[[1]]))
#> [1] 2
writeLines("The lowest (i.e. most negative) deterministic LTRE contribution: ")
#> The lowest (i.e. most negative) deterministic LTRE contribution:
min(trialltre_det$ltre_det[[1]])
#> [1] -0.2194744
writeLines("The lowest deterministic LTRE contribution is associated with element: ")
#> The lowest deterministic LTRE contribution is associated with element:
which(trialltre_det$ltre_det[[1]] == min(trialltre_det$ltre_det[[1]]))
#> [1] 4

writeLines("\nThe greatest (i.e most positive) stochastic mean LTRE contribution: ")
#> 
#> The greatest (i.e most positive) stochastic mean LTRE contribution:
max(trialltre_sto$ltre_mean[[1]])
#> [1] 0.0179472
writeLines("The greatest stochastic mean LTRE contribution is associated with element: ")
#> The greatest stochastic mean LTRE contribution is associated with element:
which(trialltre_sto$ltre_mean[[1]] == max(trialltre_sto$ltre_mean[[1]]))
#> [1] 3
writeLines("The lowest (i.e. most negative) stochastic mean LTRE contribution: ")
#> The lowest (i.e. most negative) stochastic mean LTRE contribution:
min(trialltre_sto$ltre_mean[[1]])
#> [1] -0.3709379
writeLines("The lowest stochastic mean LTRE contribution is associated with element: ")
#> The lowest stochastic mean LTRE contribution is associated with element:
which(trialltre_sto$ltre_mean[[1]] == min(trialltre_sto$ltre_mean[[1]]))
#> [1] 13

writeLines("\nThe greatest (i.e most positive) stochastic SD LTRE contribution: ")
#> 
#> The greatest (i.e most positive) stochastic SD LTRE contribution:
max(trialltre_sto$ltre_sd[[1]])
#> [1] 0.01444178
writeLines("The greatest stochastic SD LTRE contribution is associated with element: ")
#> The greatest stochastic SD LTRE contribution is associated with element:
which(trialltre_sto$ltre_sd[[1]] == max(trialltre_sto$ltre_sd[[1]]))
#> [1] 13
writeLines("The lowest (i.e. most negative) stochastic SD LTRE contribution: ")
#> The lowest (i.e. most negative) stochastic SD LTRE contribution:
min(trialltre_sto$ltre_sd[[1]])
#> [1] -0.01033674
writeLines("The lowest stochastic SD LTRE contribution is associated with element: ")
#> The lowest stochastic SD LTRE contribution is associated with element:
which(trialltre_sto$ltre_sd[[1]] == min(trialltre_sto$ltre_sd[[1]]))
#> [1] 16

writeLines("\nTotal positive contribution of shifts in deterministic LTRE contributions: ")
#> 
#> Total positive contribution of shifts in deterministic LTRE contributions:
sum(trialltre_det$ltre_det[[1]][which(trialltre_det$ltre_det[[1]] > 0)])
#> [1] 0.02675275
writeLines("Total negative contribution of shifts in deterministic LTRE contributions: ")
#> Total negative contribution of shifts in deterministic LTRE contributions:
sum(trialltre_det$ltre_det[[1]][which(trialltre_det$ltre_det[[1]] < 0)])
#> [1] -0.5586999
writeLines("\nTotal positive contribution of shifts in stochastic mean LTRE contributions: ")
#> 
#> Total positive contribution of shifts in stochastic mean LTRE contributions:
sum(trialltre_sto$ltre_mean[[1]][which(trialltre_sto$ltre_mean[[1]] > 0)])
#> [1] 0.04472458
writeLines("Total negative contribution of shifts in stochastic mean LTRE contributions: ")
#> Total negative contribution of shifts in stochastic mean LTRE contributions:
sum(trialltre_sto$ltre_mean[[1]][which(trialltre_sto$ltre_mean[[1]] < 0)])
#> [1] -0.5097578
writeLines("\nTotal positive contribution of shifts in stochastic SD LTRE contributions: ")
#> 
#> Total positive contribution of shifts in stochastic SD LTRE contributions:
sum(trialltre_sto$ltre_sd[[1]][which(trialltre_sto$ltre_sd[[1]] > 0)])
#> [1] 0.01514195
writeLines("Total negative contribution of shifts in stochastic SD LTRE contributions: ")
#> Total negative contribution of shifts in stochastic SD LTRE contributions:
sum(trialltre_sto$ltre_sd[[1]][which(trialltre_sto$ltre_sd[[1]] < 0)])
#> [1] -0.01834664

The output for the deterministic LTRE shows that element 4, which is the growth transition from seedling to large flowering adult (column 1, row 4), has the strongest influence. This contribution is negative, so it reduces \(\lambda\). The most positive contribution to \(\lambda\) is from element 2, which is the growth transition from seedling to vegetative adult (column 1, row 2). We also see the most positive contribution from shifts in mean elements in the sLTRE is from element 3 (transition from seedling to small flowering adult), but the overall greatest impact is a negative contribution from element 13, which is the fecundity transition from large flowering adult to seedling (column 4, row 1). Variability in elements also contributes to shifts in \(\text{log} \lambda\), though less so than shifts in mean elements. The strongest positive contribution is from variation in the fecundity transition from large flowering adult to seedling (element 13 in column 4, row 1), while the most negative contribution is from stasis as a large flowering adult (element 16 in row and column 4).

Second, we will identify which stages exert the strongest impact on the population growth rate.

ltre_pos <- trialltre_det$ltre_det[[1]]
ltre_neg <- trialltre_det$ltre_det[[1]]
ltre_pos[which(ltre_pos < 0)] <- 0
ltre_neg[which(ltre_neg > 0)] <- 0

sltre_meanpos <- trialltre_sto$ltre_mean[[1]]
sltre_meanneg <- trialltre_sto$ltre_mean[[1]]
sltre_meanpos[which(sltre_meanpos < 0)] <- 0
sltre_meanneg[which(sltre_meanneg > 0)] <- 0

sltre_sdpos <- trialltre_sto$ltre_sd[[1]]
sltre_sdneg <- trialltre_sto$ltre_sd[[1]]
sltre_sdpos[which(sltre_sdpos < 0)] <- 0
sltre_sdneg[which(sltre_sdneg > 0)] <- 0

ltresums_pos <- cbind(colSums(ltre_pos), colSums(sltre_meanpos), colSums(sltre_sdpos))
ltresums_neg <- cbind(colSums(ltre_neg), colSums(sltre_meanneg), colSums(sltre_sdneg))

ltre_as_names <- trialltre_det$ahstages$stage

barplot(t(ltresums_pos), beside = T, col = c("black", "grey", "red"),
  ylim = c(-0.40, 0.10))
barplot(t(ltresums_neg), beside = T, col = c("black", "grey", "red"), add = TRUE)
abline(0, 0, lty= 3)
text(cex=1, y = -0.45, x = seq(from = 2, to = 3.98*length(ltre_as_names),
    by = 4), ltre_as_names, xpd=TRUE, srt=45)
legend("bottomleft", c("deterministic", "stochastic mean", "stochastic SD"),
  col = c("black", "grey", "red"), pch = 15, bty = "n")

Figure 9.3. LTRE contributions by stage in population C

The output above shows that large flowering adults exert the strongest influence on both \(\lambda\) and \(\text{log} \lambda\), with the latter influence being through the impact of shifts in the mean. This impact is overwhelmingly negative. The next largest impact comes from seedlings in the deterministic case, and from small flowering adults in the stochastic case, in both cases the influence being negative on the whole.

Finally, we will assess what transition types exert the greatest impact on population growth rate.

det_ltre_summary <- summary(trialltre_det)
sto_ltre_summary <- summary(trialltre_sto)

ltresums_tpos <- cbind(det_ltre_summary$ahist_det$matrix1_pos,
  sto_ltre_summary$ahist_mean$matrix1_pos,
  sto_ltre_summary$ahist_sd$matrix1_pos)
ltresums_tneg <- cbind(det_ltre_summary$ahist_det$matrix1_neg,
  sto_ltre_summary$ahist_mean$matrix1_neg,
  sto_ltre_summary$ahist_sd$matrix1_neg)

barplot(t(ltresums_tpos), beside = T, col = c("black", "grey", "red"),
  ylim = c(-0.50, 0.10))
barplot(t(ltresums_tneg), beside = T, col = c("black", "grey", "red"),
  add = TRUE)
abline(0, 0, lty = 3)
text(cex=0.85, y = -0.54, x = seq(from = 2, to = 3.98*length(det_ltre_summary$ahist_det$category),
    by = 4), det_ltre_summary$ahist_det$category, xpd=TRUE, srt=45)
legend("bottomleft", c("deterministic", "stochastic mean", "stochastic SD"),
  col = c("black", "grey", "red"), pch = 15, bty = "n")

Figure 9.4. LTRE contributions by transition type in population C

The overall greatest impact on the population growth rate is from growth transitions in the deterministic case, but from fecundity transitions in the stochastic case. Clearly temporal variation has strong effects here that deserve to be assessed properly.

Let’s now turn to a comparison of the populations, focusing on the sLTRE so that we can compare the impacts of shifts in the temporal means and standard deviations of matrix elements on the stochastic growth rate. We will particularly focus on the question of how different sorts of transitions impact the stochastic growth rate, and also see if we can reproduce Figure 7 from Davison et al. (2010). To achieve this, we will first need to sort the positive and negative contributions for each transition type within each population. We will sort the resulting data frames in the transition order presented in that figure, to stay as true as possible to the paper.

sltre_meanpos_toplot <- sto_ltre_summary$ahist_mean[,seq(from = 3, by = 3, length.out = 9)]
sltre_meanneg_toplot <- sto_ltre_summary$ahist_mean[,seq(from = 4, by = 3, length.out = 9)]
sltre_sdpos_toplot <- sto_ltre_summary$ahist_sd[,seq(from = 3, by = 3, length.out = 9)]
sltre_sdneg_toplot <- sto_ltre_summary$ahist_sd[,seq(from = 4, by = 3, length.out = 9)]

colnames(sltre_meanpos_toplot) <- trialltre_sto$labels$patch
colnames(sltre_meanneg_toplot) <- trialltre_sto$labels$patch
colnames(sltre_sdpos_toplot) <- trialltre_sto$labels$patch
colnames(sltre_sdneg_toplot) <- trialltre_sto$labels$patch

rownames(sltre_meanpos_toplot) <- c("Stasis", "Growth", "Shrinkage", "Fecundity")
rownames(sltre_meanneg_toplot) <- c("Stasis", "Growth", "Shrinkage", "Fecundity")
rownames(sltre_sdpos_toplot) <- c("Stasis", "Growth", "Shrinkage", "Fecundity")
rownames(sltre_sdneg_toplot) <- c("Stasis", "Growth", "Shrinkage", "Fecundity")

sltre_meanpos_toplot <- sltre_meanpos_toplot[c(4, 3, 1, 2),]
sltre_meanneg_toplot <- sltre_meanneg_toplot[c(4, 3, 1, 2),]
sltre_sdpos_toplot <- sltre_sdpos_toplot[c(4, 3, 1, 2),]
sltre_sdneg_toplot <- sltre_sdneg_toplot[c(4, 3, 1, 2),]

Now let’s plot the contributions of shifts in the mean. Remember that all of these comparisons are against a grand mean matrix representing all populations. Note that in the code below, we use the barplot() function twice to produce a single plot - the add = TRUE setting in the second call allows us to overlay the negative contributions on the plot produced in the first call.

barplot(as.matrix(sltre_meanpos_toplot), main = "sLTRE impacts of shifts in mean", 
  xlab = "Population", ylab = "Contribution to stochastic growth rate",
  ylim = c(-0.8, 0.6), col = c("darkblue", "cyan", "yellow", "darkred"),
  legend.text = rownames(sltre_meanpos_toplot), beside = FALSE, args.legend = c(x = "topleft", bty = "n"))
barplot(as.matrix(sltre_meanneg_toplot), main = "sLTRE impacts of shifts in mean", 
  add = TRUE, col = c("darkblue", "cyan", "yellow", "darkred"),
  beside = FALSE)
abline(0, 0, lty = 2)

Figure 9.5. Mean element sLTRE contributions by transition type

Shifts in the mean appear to be strongly influential in some patches. In particular, it seems that populations L and Q, and perhaps R and F, have large impacts from the different transitions. It also appears that fecundity and growth have typically large impacts, and that these impacts are typically negative, while shifts in stasis and shrinkage transitions have little effect.

Let’s now compare with shifts in the standard deviations of matrix elements.

barplot(as.matrix(sltre_sdpos_toplot), main = "sLTRE impacts of shifts in SD", 
  xlab = "Population", ylab = "Contribution to stochastic growth rate",
  ylim = c(-0.06, 0.13), col = c("darkblue", "cyan", "yellow", "darkred"),
  legend.text = rownames(sltre_sdpos_toplot), beside = FALSE, args.legend = c(x = "topleft", bty = "n"))
barplot(as.matrix(sltre_sdneg_toplot), main = "sLTRE impacts of shifts in mean", 
  add = TRUE, col = c("darkblue", "cyan", "yellow", "darkred"),
  beside = FALSE)
abline(0, 0, lty = 2)

Figure 9.6. Element SD sLTRE contributions by transition type

We can see that shifts in the standard deviation appear to have small effects relative to shifts in the mean. The biggest shifts appear to be from fecundity, and that only in populations R and L. Other transitions have seemingly little effect.

LTREs and sLTREs are powerful tools, and more complex versions of both analyses exist. Please consult Caswell (2001) and Davison et al. (2013) for more information.

Further analytical tools are being planned for lefko3, but packages that handle projection matrices can typically handle the individual matrices produced and saved in lefkoMat objects in this package. Differences, obscure results, and errors sometimes arise when packages are not made to handle large and/or sparse matrices - historical matrices are both, and so care must be taken with their analysis.

Literature cited

Caswell, Hal. 2001. Matrix Population Models: Construction, Analysis, and Interpretation. Second edition. Sunderland, Massachusetts, USA: Sinauer Associates, Inc.
Davison, Raziel, Hans Jacquemyn, Dries Adriaens, Olivier Honnay, Hans de Kroon, and Shripad Tuljapurkar. 2010. “Demographic Effects of Extreme Weather Events on a Short-Lived Calcareous Grassland Species: Stochastic Life Table Response Experiments.” Journal of Ecology 98 (2): 255–67. https://doi.org/10.1111/j.1365-2745.2009.01611.x.
Davison, Raziel, Florence Nicolé, Hans Jacquemyn, and Shripad Tuljapurkar. 2013. “Contributions of Covariance: Decomposing the Components of Stochastic Population Growth in Cypripedium Calceolus.” The American Naturalist 181 (3): 410–20. https://doi.org/10.1086/669155.
Honnay, Olivier, Els Coart, Jan Butaye, Dries Adriaens, Sabine van Glabeke, and Isabel Roldán-Ruiz. 2006. “Low Impact of Present and Historical Landscape Configuration on the Genetics of Fragmented Anthyllis Vulneraria Populations.” Biological Conservation 127 (4): 411–19. https://doi.org/10.1016/j.biocon.2005.09.006.
Krauss, Jochen, Ingolf Steffan-Dewenter, and Tscharntke. 2004. “Landscape Occupancy and Local Population Size Depends on Host Plant Distribution in the Butterfly Cupido Minimus.” Biological Conservation 120 (3): 355–61. https://doi.org/10.1016/j.biocon.2004.03.007.
Piessens, Katrien, Dries Adriaens, Hans Jacquemyn, and Olivier Honnay. 2009. “Synergistic Effects of an Extreme Weather Event and Habitat Fragmentation on a Specialised Insect Herbivore.” Oecologia 159 (1): 117–26. https://doi.org/10.1007/s00442-008-1204-x.