Functional Weave
Code in TypeScript

health.egfr@1.0.0

README.md

2,957 bytes · view raw

# health.egfr

Status: needs review and sign-off by a qualified clinician before it is published. Not a medical device; for decision support only; always follow local clinical guidelines.

Estimated glomerular filtration rate in mL/min/1.73 m² by the **CKD-EPI 2021
creatinine equation without race** (Inker et al., NEJM 2021):

    eGFR = 142 × min(Scr/κ, 1)^α × max(Scr/κ, 1)^-1.200 × 0.9938^age × 1.012 [if female]

| | female | male |
|---|---|---|
| κ | 0.7 | 0.9 |
| α | -0.241 | -0.302 |

Scr is standardised (IDMS-traceable) serum creatinine in mg/dL; age is in
years. Creatinine in µmol/L, as UK laboratories report it, is divided by 88.4
first (the paper's conversion: mg/dL × 88.4 = µmol/L).

## What comes back

- `value`: the estimate rounded half away from zero to one decimal place.
- `reported`: the whole number a laboratory reports, rounded from the
  **unrounded** estimate. Rounding the one-decimal value again is a double
  rounding: a man of 18 with 0.6 mg/dL is 143.4993, which is 143.5 to one
  place and 143 as a whole number, not 144.

Laboratories often print values above 90 as "> 90"; that presentation is the
caller's. Staging (G1 to G5) and the decision to act on a result are
clinical, and not done here.

## Inputs

- **Unit is explicit.** `umol-per-l` or `mg-per-dl`. Each has its own range,
  10 to 4000 µmol/L and 0.1 to 45 mg/dL, so a value in the wrong unit (80
  given as mg/dL, 0.9 given as µmol/L) is refused instead of producing a
  plausible-looking wrong answer. The ranges are guard rails for a clinician
  to confirm; they are not from the paper.
- **Adults only**, 18 to 120 whole years; the equation was developed and
  validated in adults.
- **Sex** is `female` or `male`, as the coefficients need one of the two.
- Nothing is clamped: an out-of-range input is an error.

## Precision

Every power goes through `math.pow` (never the platform `Math.pow` or
`powf`), which returns the same double in TypeScript, Python and Rust, and the
rounding is `math.round-float`, so the vectors compare exactly. The paper
gives no worked example; the vectors were computed from the equation to 60
significant digits, independently of this implementation.

## Source

Inker LA, Eneanya ND, Coresh J, et al., for the Chronic Kidney Disease
Epidemiology Collaboration. *New Creatinine- and Cystatin C-Based Equations to
Estimate GFR without Race.* N Engl J Med 2021;385(19):1737-1749.
doi:10.1056/NEJMoa2102953 (PMC8822996). Table 2, row "2021 CKD-EPI creatinine
(2009 CKD-EPI creatinine fit without race); eGFRcr(AS), new": 142; F -0.241,
M -0.302; -1.200; 0.9938; 1.012; with the footnote "κ is 0.7 for female
participants and 0.9 for male participants". Read from the PubMed Central full
text. The same equation and constants are published by the National Kidney
Foundation (https://www.kidney.org/ckd-epi-creatinine-equation-2021) and the
NIDDK, which also gives the µmol/L conversion (divide by 88.4).