disappR is an R package providing a Shiny app for diagnosing and modelling selective disappearance and selective appearance in longitudinal ageing data.
Most ageing studies want the average within-individual ageing pattern, but most of the time there is only population-level data on individuals, and that data is almost never complete. Individuals die, emigrate or are simply missed, and others only enter the study part-way through their life. If the individuals that leave early or arrive late differ in the trait being measured, the population-level pattern stops reflecting how individuals age. Standard analyses are then at risk of bias.
disappR works through this in a logical order. If first shows whether selective disappearance or appearance is visible in your data, then checks how complete your sampling is and what shape ageing takes, and only then fits and compares a set of ten mixed models built to separate the two processes. Every panel explains what it shows and how to read it, and everything you run can be exported as R code.
- Visual diagnosis before modelling. Trait trajectories of lifespan and age-at-entry groups, how far apart those groups are at each age, the trait before death, selection differentials by age and the disappearance hazard.
- Sampling and missingness checks. When each individual was actually seen, how much data is missing and at which ages, whether missingness tracks the trait, and which lifespan proxy to use.
- Individual and population trajectories. An ageing function fitted to each individual, the average within-individual trajectory rebuilt from those fits, and a comparison of ageing functions at both levels.
- Ten comparative mixed models, from a naive model to models for age-independent and age-dependent selective disappearance and appearance, with Gaussian, Poisson, negative binomial, zero-inflated, binomial and beta-binomial families.
- Checks on the fitted models. Likelihood-ratio tests, residual diagnostics (DHARMa and performance), error-family and ageing-function checks, effect sizes and a null-model bootstrap for the lifespan effect.
- Teaching simulations. Generate data with a known true trajectory, choosing the ageing shape, the sampling design and the type and strength of selection, and see how close each model gets to the truth.
- 13 published datasets from 12 studies of laboratory and wild populations, each set up to reproduce the analysis in its paper.
- Reproducible output. Downloadable R code for every section, HTML and text reports, the analysis data, and a reproducibility bundle of every setting used.
- Runs locally. Your data never leave your machine.
disappR is not on CRAN. Install the development version from GitHub:
install.packages("devtools")
devtools::install_github("EIvimeyCook/disappR")The app needs shiny, shinydashboard, ggplot2 and lme4, which are
installed automatically. The packages below are optional. Without them the app
still runs with fewer analyses, and the Start here page lists anything that is
missing.
install.packages(c("glmmTMB", "lmerTest", "nlme", "DHARMa", "performance", "see", "codetools", "callr"))| Package | Enables |
|---|---|
glmmTMB |
Count, proportion and binary traits |
lmerTest |
p-values for Gaussian models |
nlme |
The non-linear exponential ageing function |
DHARMa |
Simulation-based residual checks |
performance, see |
Model diagnostics and their plots |
codetools |
Exported R code |
callr |
Runs the trajectory fits in a separate R process, so a failure there cannot stop the app |
Video walkthrough here.
library(disappR)
run_app()This opens the app in your browser or the RStudio viewer.
If you would rather not install the package, you can run the app straight from a downloaded copy of the repository:
shiny::runApp("path/to/disappR/inst/app")The app is laid out as six numbered steps in the left-hand sidebar. You can move between them freely, but each builds on the one before.
Start here. An overview of the problem and the workflow. The Quick start buttons load a simulated dataset where the answer is known, or opens the list of published examples. This page also lists which optional packages are installed.
- Data — choose a data source: simulated teaching data, one of the 13 published datasets, or your own CSV (one row per individual per sampling occasion). Then map your columns: individual ID, age and trait are required, and lifespan, age at first observation, covariates, groups and censoring are optional (see Preparing your data). The Data integrity checks panel flags anything that looks wrong, such as repeated records, IDs shared between groups, or an individual whose lifespan differs between its rows. You can also subset the data and look at the distribution of any variable.
- Visual diagnosis — does the phenotype of long- and short-lived (or early- and late-entering) individuals differ, and does that difference change with age? A constant gap between groups points to age-independent selection; a gap that widens or narrows with age points to age-dependent selection. Further panels look at the trait just before death, whether survivors differ from those that disappear at each age, and the age-specific disappearance hazard.
- Missingness and proxies — a grid of when each individual was actually seen, how much is missing at each age, and whether what is missing is related to the trait. This step also compares age at last record (ALR) and individual mean age as proxies for lifespan, which tells you which of the models in step 5 to trust.
- Trajectories — fits linear, quadratic, cubic, logarithmic, asymptotic and exponential functions to each individual, rebuilds the average within-individual trajectory from those fits, and compares the functions at the individual and population level. Use the best-supported function as the ageing function in step 5.
- Modelling — choose the error family, random effects (intercepts, or correlated or uncorrelated random slopes), the ageing function and any covariates, tick the models you want, and press Fit models. The results show which selective processes the data support, likelihood-ratio tests between nested models, coefficients in original units, predicted population trajectories, and a set of checks on the fits.
- Summary and report — every result you saved with a Save to summary button is collected here, along with an evidence summary that grades what the saved results suggest about selective disappearance and appearance. Export it as an HTML report (with plots) or a text report, alongside the R script, the analysis data and a reproducibility bundle.
Tip. Start with the simulated data before loading your own. The simulated datasets make the patterns deliberately obvious, and on the Modelling tab the app scores each model against the true trajectory, so you can see what each diagnostic looks like when you already know the answer.
Tip. Click the ⓘ next to any panel title for what it shows, how to read it and what to watch out for. The ⓘ next to each model in the model settings gives its exact specification.
Data should be a CSV with one row per individual per sampling occasion.
| Column | Required? | Notes |
|---|---|---|
| Individual ID | Yes | Can be nested within a group (for example family), and within a second level above that |
| Age | Yes | Numeric, in any unit; can be rounded to a set resolution |
| Trait | Yes | Continuous, count, proportion or binary (0/1) |
| Age at last record (ALR) | No | Worked out from each individual's last row if not mapped |
| Known lifespan (LS) | No | Map only if lifespan is truly known; enables Model 6 |
| Age at first observation (AFR) | No | Worked out from each individual's first row if not mapped; enables Models 7–10 |
| Censoring | No | Marks individuals still alive at the end of the study |
| Covariates | No | Continuous or categorical, with optional interactions with age or with each other |
| Group / random effects | No | Grouping variables and additional random intercepts |
| Number of trials | No | For proportion traits with the binomial families (chosen on the Modelling tab) |
Each individual must have a single ALR, lifespan and AFR. If a mapped column gives an individual different values in different rows, loading stops and names the individuals involved; you can then fix the data or tick the box to exclude them. Repeated records of the same individual at the same age can be kept or averaged.
With b(age) the chosen ageing function (for example age + age²), mean(age)
an individual's mean age and Δb(age) its within-individual deviation:
| Model | Fixed effects | What it tests |
|---|---|---|
| 1 | b(age) | Naive model: selection not accounted for |
| 2 | b(age) + ALR | Age-independent selective disappearance |
| 3 | mean(age) + Δb(age) | Age-independent selective disappearance, by mean-age centring |
| 4 | b(age) × ALR | Age-dependent selective disappearance (ALR) |
| 5 | mean(age) × Δb(age) | Age-dependent selective disappearance (mean age) |
| 6 | b(age) × LS | Positive control when lifespan is known |
| 7 | b(age) + ALR + AFR | Age-independent disappearance and appearance |
| 8 | b(age) × ALR + b(age) × AFR | Age-dependent disappearance and appearance |
| 9 | b(age) × ALR + AFR | Age-dependent disappearance, age-independent appearance |
| 10 | b(age) + ALR + b(age) × AFR | Age-independent disappearance, age-dependent appearance |
Mapped covariates enter every model, and all models are fitted by maximum likelihood to the same rows, so their AICs can be compared directly. The models-and-methods vignette gives the full specification of each.
The simulator generates longitudinal data with a known true ageing trajectory. You can set the trait and its distribution (body mass, or fecundity as Poisson, negative binomial or zero-inflated counts), the ageing form and a biological scenario within it (for example slow or fast senescence, an early or late peak, or terminal investment), mean lifespan, individual variation in ageing rates, the type and direction of selective disappearance and appearance, the sampling design (including several kinds of missingness), a diet covariate, families as a nested random effect, the number of individuals and the seed. Each simulation lists what you should expect to see, and the simulated data can be downloaded as a CSV.
Thirteen published datasets are bundled, each opening with the settings that most closely reproduce the analysis in its paper:
- Sanghvi et al. 2025, American Naturalist — Drosophila melanogaster daily fecundity
- Sanghvi et al. 2022, Evolution — seed beetle female fecundity
- Bichet et al. 2022, Journal of Animal Ecology — common tern immune parameters
- Bichet et al. 2022, Ecology and Evolution — Alpine marmot immune parameters
- Wynn et al. 2025, Journal of Animal Ecology — common tern navigational efficiency
- Moullec et al. 2023, Frontiers in Ecology and Evolution — Alpine swift reproduction
- Pásztor et al. 2022, Ecology and Evolution — clouded Apollo butterfly body size
- Allain et al. 2023, Oikos — eastern chipmunk reproduction
- Bouwhuis et al. 2009, Proc. R. Soc. B — great tit recruit production
- Warner et al. 2016, PNAS — painted turtle reproduction
- McKenna-Ell et al. 2023, Biology Letters — Soay sheep breeding probability and offspring survival
- McKenna-Ell et al. 2023, Biology Letters — Soay sheep offspring birth weight
- Szejner-Sigal et al. 2025, Proc. R. Soc. B — alfalfa leafcutting bee locomotor activity
Sources and licences for each are listed in
inst/app/data/PROVENANCE.md.
The functions behind the app can also be used directly in R scripts:
library(disappR)
sim <- disappr_simulate(n_id = 150, seed = 1, sd_type = "both")
map <- disappr_mapping(id = "ID", age = "age", trait = "body_mass", life = "lifespan")
x <- disappr_prepare(sim, map)
fit <- disappr_fit(x, models = c("M1", "M2", "M4"), age_function = "Quadratic")
disappr_compare(fit) # AIC table
disappr_predict(fit, "M4") # predicted population trajectory
cat(disappr_code(fit, x)) # R code that reproduces the analysis| Function | Purpose |
|---|---|
disappr_read() |
Read a CSV or other delimited file |
disappr_example() |
Load a bundled dataset with its published settings |
disappr_simulate() |
Simulate data with a known trajectory |
disappr_mapping() |
Say which column holds which variable |
disappr_prepare() |
Check and standardise the data |
disappr_fit() |
Fit and compare Models 1–10 |
disappr_compare() |
The AIC table |
disappr_predict() |
Predicted population trajectory for one model |
disappr_diagnose() |
Fit validity, dropped rows and notes |
disappr_interpret() |
Interpretation notes |
disappr_code() |
A standalone R script for the analysis |
disappr_provenance() |
Every setting and package version used |
?disappr_api documents the arguments of each.
- Inside the app, every panel has an ⓘ button explaining what it shows and how to read it.
- The video walkthrough on OSF shows the app in use.
- An association between missingness and an observed variable cannot show whether data are missing completely at random, at random, or not at random.
- AIC measures relative support among the models fitted, not causation. Check the model comparison against the visual diagnosis and the residual checks before drawing conclusions.
- Mean age is a poor proxy for lifespan when sampling is incomplete. Step 3 tells you whether this applies to your data.
- The evidence summary on step 6 is deliberately cautious and only uses results you have saved.
Please file issues and feature requests at https://github.com/EIvimeyCook/disappR/issues. Pull requests are welcome.
- READMEBuilder — document your finished analysis for archiving
- DCQC — data and code quality control for ecology and evolutionary biology
If disappR helps with your work, please cite:
Sanghvi, K., & Ivimey-Cook, E. R. (2026). disappR: a shiny app to model ageing and selective [dis]appearance. R package. https://github.com/EIvimeyCook/disappR
and the paper describing the methods:
Sanghvi, K., Ivimey-Cook, E. R., Bouwhuis, S., Sepil, I., & van de Pol, M. (2026). A comparison of methods to assess selective disappearance and quantify ageing. EcoEvoRxiv.
Data, code and supplementary material for the paper are on
OSF. citation("disappR") gives both references, and a
machine-readable CITATION.cff is included, so GitHub's "Cite
this repository" button gives formatted APA and BibTeX.
Edward R. Ivimey-Cook — e.ivimeycook@gmail.com — ORCID 0000-0003-4910-0443
Released under the MIT License.
