The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
This vignette reproduces the analysis of the companion paper on the epiphytic orchid Lepanthes eltoroensis (Luquillo Mountains, Puerto Rico), in which reproduction is continuous in time and recruitment is episodic. The package’s tests check the numbers below against the archived outputs of the paper’s pipeline; here they are simply computed.
lepanthes_monthly
#> # A tibble: 23 × 3
#> period reproductive_adults recruits
#> <int> <int> <int>
#> 1 1 60 NA
#> 2 2 64 0
#> 3 3 84 4
#> 4 4 71 1
#> 5 5 80 0
#> 6 6 81 0
#> 7 7 86 0
#> 8 8 78 0
#> 9 9 61 0
#> 10 10 54 0
#> # ℹ 13 more rows
lepanthes_census |> select(period, census, adults, inflorescences, recruits)
#> # A tibble: 12 × 5
#> period census adults inflorescences recruits
#> <int> <chr> <int> <int> <dbl>
#> 1 1 Mar 1999 264 509 NA
#> 2 2 Sep 1999 290 218 NA
#> 3 3 Mar 2000 311 216 5
#> 4 4 Sep 2000 324 237 3
#> 5 5 Mar 2001 333 225 62
#> 6 6 Sep 2001 303 142 30
#> 7 7 Mar 2002 289 185 0
#> 8 8 Sep 2002 288 171 0
#> 9 9 Mar 2003 274 128 14
#> 10 10 Sep 2003 243 82 32
#> 11 11 Mar 2004 217 118 3
#> 12 12 Sep 2004 179 111 0
lepanthes_hosts
#> # A tibble: 276 × 5
#> host period adults inflorescences recruits
#> <chr> <int> <int> <int> <dbl>
#> 1 209 1 6 10 NA
#> 2 209 2 9 11 NA
#> 3 209 3 9 4 0
#> 4 209 4 9 5 0
#> 5 209 5 8 6 0
#> 6 209 6 7 5 1
#> 7 209 7 7 6 0
#> 8 209 8 7 3 0
#> 9 209 9 8 1 0
#> 10 209 10 10 3 1
#> # ℹ 266 more rowsThe monthly survey (1994 to 1996) counts inflorescence-bearing adults
and new seedlings at 23 monthly censuses of four populations; recruits
are defined by first appearance, so they are scored from census 2. The
six-monthly survey (1999 to 2004) counts every plant on 23 host trees at
12 censuses; recruits are scored at censuses 3 to 12.
lepanthes_census holds its system totals and
lepanthes_hosts one row per host tree and census, which is
the input of the host-level test.
The lag conventions differ, and the package makes them explicit. The
monthly lag model of the paper reads lag k at month t -
k over a six-month horizon (K = 6,
lag0 = 0). The six-monthly model reads lag k at
census t - 1 - k over five six-month bins (K = 4,
lag0 = 1). The bins are labelled 0-6, 6-12, 12-18, 18-24
and 24-30 months, counted from the first lagged census, which is the
convention of the kernel labels throughout.
k_m <- lag_kernels(6, bin = 1, unit = "mo")
k_6 <- lag_kernels(4, bin = 6, unit = "mo")
c_m <- lag_ceiling(lepanthes_monthly, reproduction = "reproductive_adults", K = 6, lag0 = 0, kernels = k_m)
c_6 <- lag_ceiling(lepanthes_census, reproduction = "inflorescences", K = 4, lag0 = 1, kernels = k_6)
c_m
#> Ceiling on the concentration of expected recruitment
#> reproductive record: 23 periods; recruits scored at 22 periods; K = 6, lag0 = 0
#> reproduction (theorem bound) Gini 0.089 CV 0.159
#> searched ceiling Gini 0.095 CV 0.173 (pure delay 6-7 mo, 33 kernels)
#> observed recruitment Gini 0.859 CV 2.749
#> exceedance (obs / ceiling) Gini 9.00 CV 15.88
#> The exceedance bounds the expected series, not the counts; see ceiling_calibration() and host_lag_test().
c_6
#> Ceiling on the concentration of expected recruitment
#> reproductive record: 12 periods; recruits scored at 10 periods; K = 4, lag0 = 1
#> reproduction (theorem bound) Gini 0.259 CV 0.570
#> searched ceiling Gini 0.254 CV 0.547 (pure delay 12-18 mo, 20 kernels)
#> observed recruitment Gini 0.649 CV 1.377
#> exceedance (obs / ceiling) Gini 2.56 CV 2.51
#> The exceedance bounds the expected series, not the counts; see ceiling_calibration() and host_lag_test().At both time scales the ceiling is low because the input is flat, the searched maximum is attained by a pure delay and lies within 0.01 of the theorem bound (the small difference arises from backfilling pre-record lags), and observed recruitment exceeds the ceiling by a factor of about 9 (monthly) and 2.6 (six-monthly) on the Gini.
profiles <- list(
`one interval only (projection-matrix null)` = c(1, 0, 0, 0, 0),
`concentrated early (0 to 6 months)` = c(.7, .2, .07, .03, 0),
`evenly spread (0 to 30 months)` = rep(.2, 5),
`concentrated late (24 to 30 months)` = c(0, .03, .07, .2, .7),
`fitted posterior mean` = lepanthes_profile$weight)
rain_profiles(profiles, bin = 6, unit = "months")The expected series all but coincide and follow the slow decline of reproduction; none resembles the recruits counted (62 at census 5, none at censuses 7, 8 and 12, 32 at census 10). The fitted posterior-mean profile from the paper’s distributed-lag model is among them and is indistinguishable from the rest, which is the identification problem the paper describes: with a flat input the lag cannot be recovered, however long the series.
The ceiling is arithmetic and carries no uncertainty. The two concentration indices it is compared with are estimates from ten censuses, and so is their ratio, and a reader is entitled to an interval on them. The package gives three, because they answer differently worded questions and a user should take the one whose logic they accept.
The first resamples the 23 host trees with replacement, rebuilds both series from the resampled trees, and recomputes the ceiling and the exceedance in each replicate. It is a confidence interval, BCa by default, and is read in the usual way. The share of replicates at or below 1 is reported as what it is, a one-sided bootstrap p-value, and not as a probability that the exceedance is at most 1.
set.seed(20260913)
k4 <- lag_kernels(4, bin = 6, unit = "mo")
lag_ceiling_boot(lepanthes_hosts, unit = "host", reproduction = "inflorescences",
K = 4, kernels = k4, R = 2000)
#> Cluster bootstrap of the ceiling: 23 units resampled 2000 times, 90% BCa intervals
#> estimand: realised counts; K = 4, lag0 = 1, 20 kernels
#> observed Gini 0.649 [0.578, 0.694]
#> ceiling Gini 0.254 [0.196, 0.291]
#> exceedance Gini 2.56 [2.11, 3.18]
#> observed CV 1.377 [1.143, 1.598]
#> ceiling CV 0.547 [0.426, 0.637]
#> exceedance CV 2.51 [1.94, 3.27]
#> one-sided bootstrap p-value for exceedance <= 1: Gini < 5e-04, CV < 5e-04
#> A confidence interval, read in the usual way; p_boot is not a posterior probability.The second is Rubin’s Bayesian bootstrap: Dirichlet weights over the
hosts in place of resampling, and a posterior in place of a sampling
distribution. The numbers are close to the first, which is expected; the
difference is that P(exceedance > 1) is now a posterior
probability under a stated prior and may be written as one.
lag_ceiling_bayesboot(lepanthes_hosts, unit = "host", reproduction = "inflorescences",
K = 4, kernels = k4, draws = 4000)
#> Bayesian bootstrap of the ceiling: 23 units, 4000 posterior draws, 90% equal-tailed credible intervals
#> estimand: realised counts; K = 4, lag0 = 1, 20 kernels
#> observed Gini 0.649 [0.609, 0.731]
#> ceiling Gini 0.254 [0.222, 0.318]
#> exceedance Gini 2.56 [2.06, 3.07]
#> observed CV 1.377 [1.228, 1.809]
#> ceiling CV 0.547 [0.462, 0.669]
#> exceedance CV 2.51 [2.04, 3.46]
#> P(exceedance > 1): Gini > 0.9998, CV > 0.9998The third fits a negative-binomial model to the counts on every host
at every census, with host and census effects, and puts the posterior of
the expected series through the same ceiling
arithmetic. That is the object the bound applies to, and its exceedance
is lower than the raw one, because part of the concentration of small
counts is sampling variation about a smoother mean. It needs
cmdstanr and CmdStan, so it is not run here.
set.seed(20260903)
cal <- ceiling_calibration(c_6)
cal
#> Observed recruitment: Gini 0.649, CV 1.377, 3 zero periods of 10
#> Simulated counts about a mean that obeys the ceiling:
#> # A tibble: 2 × 11
#> null phi gini_med gini_q05 gini_q95 p_gini cv_med cv_q05
#> * <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 N0 flat mean 0.547 0.570 0.408 0.72 0.207 1.19 0.781
#> 2 N1 best-kernel mean 0.547 0.598 0.424 0.756 0.306 1.28 0.818
#> cv_q95 p_cv p_zeros
#> * <dbl> <dbl> <dbl>
#> 1 1.81 0.279 0.203
#> 2 2.05 0.394 0.245
#> p_* is the probability that a simulated series is at least as concentrated as the observed one.About a mean that obeys the ceiling, negative-binomial counts with the observed variance-to-mean ratio produce a series as concentrated as the observed one roughly one time in 3. The exceedance of the ceiling by the pooled counts is therefore not evidence; the test has to be made across host trees.
lepanthes_hosts |>
filter(!is.na(recruits)) |>
group_by(period) |>
summarise(recruits = sum(recruits), hosts_recruiting = sum(recruits > 0))
#> # A tibble: 10 × 3
#> period recruits hosts_recruiting
#> <int> <dbl> <int>
#> 1 3 5 1
#> 2 4 3 1
#> 3 5 62 1
#> 4 6 30 1
#> 5 7 0 0
#> 6 8 0 0
#> 7 9 14 1
#> 8 10 32 1
#> 9 11 3 1
#> 10 12 0 0Three of the ten censuses are silent (no recruit on any of the 23 hosts) and one carries 62. Under the lag hypothesis, expected recruitment on each host is that host’s own lagged inflorescence record, scaled to its own total. The kernels are the pure delays, every uniform window, geometric decay and the fitted profile; the paper adds 800 Dirichlet draws, which take longer and change nothing.
set.seed(20260910)
ht <- host_lag_test(lepanthes_hosts, unit = "host", reproduction = "inflorescences",
K = 4, nsim = 4000,
kernels = lag_kernels(4, bin = 6, unit = "mo",
extra = list(`fitted posterior mean` = lepanthes_profile$weight)),
phi = 0.089)
ht
#> Host-level test of the lag hypothesis: 23 units, 10 censuses, 21 profiles, 4000 simulations each
#> observed census totals: 3 silent, Gini 0.649, CV 1.377, largest 62
#> flat reference (phi = 0.19): P(silent) 0.0000, P(Gini) 0.0003, P(CV) 0.0030
#> most favourable profile for the lag hypothesis, by statistic:
#> moment silent P = 0.0008 (pure delay 12-18 mo)
#> moment gini P = 0.0025 (pure delay 6-12 mo)
#> moment cv P = 0.0320 (pure delay 6-12 mo)
#> moment max P = 0.1403 (pure delay 6-12 mo)
#> fixed 0.089 silent P = 0.0517 (pure delay 6-12 mo)
#> fixed 0.089 gini P = 0.1532 (pure delay 6-12 mo)
#> fixed 0.089 cv P = 0.2650 (pure delay 6-12 mo)
#> fixed 0.089 max P = 0.3320 (pure delay 12-18 mo)The moment estimate of the clumping parameter under the flat reference is about 0.19; the paper also evaluates every profile at 0.089, the estimate obtained about a single pooled mean, which attributes the between-host spread of the means to clumping and is about twice the clumping the counts support. Even at that value the most favourable profile does not make three silent censuses ordinary.
ht$verdict
#> # A tibble: 8 × 5
#> phi_source statistic observed max_p kernel
#> <chr> <chr> <dbl> <dbl> <chr>
#> 1 moment silent 3 0.00075 pure delay 12-18 mo
#> 2 moment gini 0.649 0.0025 pure delay 6-12 mo
#> 3 moment cv 1.38 0.032 pure delay 6-12 mo
#> 4 moment max 62 0.140 pure delay 6-12 mo
#> 5 fixed 0.089 silent 3 0.0518 pure delay 6-12 mo
#> 6 fixed 0.089 gini 0.649 0.153 pure delay 6-12 mo
#> 7 fixed 0.089 cv 1.38 0.265 pure delay 6-12 mo
#> 8 fixed 0.089 max 62 0.332 pure delay 12-18 mo
ht$table |>
filter(phi_source == "moment",
label %in% c("flat reference", "pure delay 24-30 mo", "uniform 0-30 mo", "fitted posterior mean")) |>
select(label, phi, gini_expected, p_silent, p_gini, p_cv)
#> # A tibble: 4 × 6
#> label phi gini_expected p_silent p_gini p_cv
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 flat reference 0.190 0 0 0.00025 0.003
#> 2 pure delay 24-30 mo 0.275 0.182 0 0 0.00725
#> 3 uniform 0-30 mo 0.285 0.138 0 0 0.00525
#> 4 fitted posterior mean 0.289 0.137 0 0 0.006No lag profile, of any shape over the 30-month window, makes the observed record ordinary. Recruitment in this population is not the delayed consequence of its own reproduction; something else opens and closes.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.