An instrument here is data, not code. The registry shows what is installed and whether each definition has been checked against its primary source:
list_instruments()
#> id
#> 1 bii
#> 2 icpi
#> 3 icsi
#> 4 iiq7
#> 5 ipss
#> 6 isi
#> 7 isi3
#> 8 oabss
#> 9 udi6
#> full_name
#> 1 Benign Prostatic Hyperplasia Impact Index (BII, 4 items)
#> 2 Interstitial Cystitis Problem Index (O'Leary-Sant)
#> 3 Interstitial Cystitis Symptom Index (O'Leary-Sant)
#> 4 Incontinence Impact Questionnaire, short form (IIQ-7), 0-100 scale
#> 5 International Prostate Symptom Score / AUA Symptom Index (7 symptom items)
#> 6 Sandvik Incontinence Severity Index, four-level (revised 2000)
#> 7 Sandvik Incontinence Severity Index, three-level (original 1993)
#> 8 Overactive Bladder Symptom Score (4 items)
#> 9 Urogenital Distress Inventory, short form (UDI-6), 0-100 scale
#> n_items scoring missing_rule validated
#> 1 4 sum none_published TRUE
#> 2 4 sum none_published TRUE
#> 3 4 sum none_published TRUE
#> 4 7 mean_scaled prorate_mean TRUE
#> 5 7 sum none_published TRUE
#> 6 2 product none_published TRUE
#> 7 2 product none_published TRUE
#> 8 4 sum none_published TRUE
#> 9 6 mean_scaled prorate_mean TRUEOne engine scores everything. Wrappers like score_ipss()
add instrument-specific conveniences, in this case the separate
quality-of-life item and severity classification:
d <- data.frame(
ipss_q1 = c(1, 3), ipss_q2 = c(2, 4), ipss_q3 = c(3, 5),
ipss_q4 = c(0, 2), ipss_q5 = c(4, 5), ipss_q6 = c(5, 3),
ipss_q7 = c(2, 4), qol = c(3, 5)
)
score_ipss(d, qol = "qol", classify = TRUE)
#> ipss_total ipss_voiding ipss_storage ipss_n_missing ipss_qol ipss_severity
#> 1 17 13 4 0 3 moderate
#> 2 26 16 10 0 5 severeMissing items are handled by the published rule for the instrument. The IPSS has no published rule, so a missing item gives NA and asking for proration is an error:
d_miss <- d
d_miss$ipss_q3[1] <- NA
score_ipss(d_miss, missing = "prorate")
#> Error: No published prorated-scoring rule exists for "ipss". uroscores will not invent one; handle missing items explicitly upstream (e.g. principled imputation) if you must.UDI-6 does have a published rule (mean of answered items, at most two missing), so it prorates by default with the published threshold:
u <- data.frame(
udi6_q1 = c(3, 0), udi6_q2 = c(3, 0), udi6_q3 = c(3, 3),
udi6_q4 = c(3, 3), udi6_q5 = c(3, NA), udi6_q6 = c(NA, NA)
)
score_instrument(u, "udi6")
#> udi6_total udi6_n_missing
#> 1 100 1
#> 2 50 2For responder analyses, look at the published statistics first, then pick a threshold on purpose:
mid_estimates("ipss")[, c("statistic", "value", "subgroup")]
#> statistic value subgroup
#> 1 mean change -3.0 all patients
#> 2 mean change -5.1 all patients
#> 3 mean change -8.8 all patients
#> 4 mean change -1.9 baseline AUA-SI 8-19
#> 5 mean change -6.1 baseline AUA-SI 20-35
#> 6 ROC cutoff -3.0 all patients
responder(baseline = c(20, 12), followup = c(14, 11), "ipss", threshold = 3)
#> [1] TRUE FALSE