Stature estimation and association application built with R/Shiny. SID uses regression-based methods to estimate stature from skeletal measurements and assess stature association strength against reference populations.
Key Features:
- Stature Estimation — predict living stature from skeletal measurements using OLS regression
- Bootstrap Prediction Intervals — optional bootstrap resampling (5000 iterations) for small reference samples (n < 100), applied per-combination with results flagged in the output table
- Stature Association — evaluate whether a known stature is consistent with skeletal measurements
- Interactive Plotly visualizations with prediction intervals
- PostgreSQL-backed reference populations (ARDS)
| Layer | Technology |
|---|---|
| Frontend | R/Shiny UI |
| Backend (statistical) | R |
| Database | PostgreSQL (ARDS) |
| Deployment | Docker (rocker/shiny) |
- Docker
- A running PostgreSQL instance with the ARDS osteometry schema
- A
.envfile insideSID/with database credentials:DB_HOST=<host> DB_PORT=<port> DB_USER=<user> DB_PASS=<password>
git clone https://github.com/dpaa-gov/SID
cd SID
docker build -t statureid .
docker run --restart=on-failure:10 --name=statureid -d -p 4002:3838 statureid
docker network connect app_bridge statureidThe app will be available at http://localhost:4002/SID.
- R 4.x with packages listed in Dependencies
- PostgreSQL client library (
libpq-devon Debian/Ubuntu) .envfile inSID/with DB credentials (see Prerequisites)
Rscript start_dev.RThe app will open at http://127.0.0.1:4002.
SID/
├── Dockerfile
├── SID/ # Shiny application
│ ├── server.r # Server entry point
│ ├── ui.r # UI entry point
│ ├── R/ # Analytical R functions
│ ├── server/ # Server modules (reference, estimation, association)
│ ├── ui/ # UI modules
│ └── www/ # Static assets (CSS, images)
└── start_dev.R # Local development launcher
| Package | Purpose |
|---|---|
| shiny | Web framework |
| plotly | Interactive plots |
| DT | Interactive data tables |
| dplyr | Data manipulation |
| shinyalert | Alert dialogs |
| DBI | Database interface |
| RPostgres | PostgreSQL driver |
| dotenv | Environment variable loading |
When enabled, bootstrap prediction intervals replace the standard normal-theory intervals from predict(lm, interval="prediction") for reference samples with n < 100. This is applied per-combination — within a single estimation run, large-sample combinations use OLS while small-sample combinations use bootstrap. The results table method column flags which approach was used.
Algorithm (per combination where n < 100):
- Point estimate from OLS on the full (non-resampled) reference data — not the bootstrap mean, so the estimate is identical whether bootstrap is on or off and avoids contamination from the
rnormnoise draws - Fit full model once to obtain fitted values (ŷᵢ) and residuals (eᵢ = yᵢ − ŷᵢ)
- For each of 5,000 bootstrap iterations:
- Resample residuals with replacement (not cases — avoids σ̂ bias from duplicate observations)
- Create synthetic response: yᵢ = ŷᵢ + eᵢ
- Refit regression on (X, y*) using
lm.fit()(no formula overhead) - Predict at the specimen value
- Draw from
N(ŷ, σ)using the full-model residual SD to incorporate observation scatter
- Derive prediction interval bounds from the percentile method on the 5,000 draws
The residual noise draw in step 2 is what distinguishes a prediction interval from a confidence interval for the mean — it captures both coefficient uncertainty and the irreducible scatter of individual observations around the regression line.
- Alex Moore — UI styling suggestions and design inspiration
Lynch, J.J. 2026 SID. Stature Identification. Version 0.1.0. Defense POW/MIA Accounting Agency, Offutt AFB, NE.
- Replace
.envfile with injected environment variables - Decide on forcing metric-only (cm) for stature in ARDS, or add a check in SID to verify/convert the unit of stature pulled from ARDS
GNU General Public License v2.0 — see LICENSE for details.
