| Title: | Clinical Outcome Measures and Responder Analysis |
|---|---|
| Description: | Validated clinical outcome-measure scoring (FMA, Berg, ARAT, TUG, 6MWT, Barthel, Katz, Lawton-Brody IADL, ...), MDC/MCID responder classification, ICF tagging, interval (Rasch) analysis of ordinal ADL/IADL instruments, and normative deviation scoring for the x-biosignal rehabilitation ecosystem. |
| Authors: | Yusuke Matsui [aut, cre] |
| Maintainer: | Yusuke Matsui <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.7.0 |
| Built: | 2026-10-03 13:42:13 UTC |
| Source: | https://github.com/x-biosignal/PhysioClinical |
Apply a score crosswalk to new values
applyEquating(equating, values)applyEquating(equating, values)
equating |
a |
values |
numeric source-scale values to convert. |
numeric target-scale equivalents (linearly interpolated within the crosswalk, clamped to its range).
set.seed(1) ability <- rnorm(200) barthel <- pmin(100, pmax(0, round((ability + 3) * 16 / 5) * 5)) fim <- pmin(126, pmax(18, round(18 + (ability + 3) * 18))) applyEquating(equateScores(barthel, fim), c(40, 60, 80))set.seed(1) ability <- rnorm(200) barthel <- pmin(100, pmax(0, round((ability + 3) * 16 / 5) * 5)) fim <- pmin(126, pmax(18, round(18 + (ability + 3) * 18))) applyEquating(equateScores(barthel, fim), c(40, 60, 80))
Convert a ClinicalScore to a one-row data.frame
## S3 method for class 'ClinicalScore' as.data.frame(x, ..., stringsAsFactors = FALSE)## S3 method for class 'ClinicalScore' as.data.frame(x, ..., stringsAsFactors = FALSE)
x |
|
... |
Ignored. |
stringsAsFactors |
Ignored (kept for the S3 generic signature). |
A one-row data.frame with the total, each subscale, the stratum and the metadata columns.
Classifies each subject's pre-to-post change with the two-criterion responder
framework (Beaton 2001; de Vet 2006): a change is cross-tabulated on whether
it exceeds the Minimal Detectable Change (is it real, above measurement
error?) and the Minimal Clinically Important Difference (is it clinically
meaningful?), giving four categories — true_responder (exceeds both),
subclinical_change (real but below MCID), measurement_error
(claims MCID but within noise, only when MCID < MDC) and
non_responder. Vectorized over subjects and direction-aware.
classifyResponder( baseline, followup, instrument = NULL, population = NULL, mdc = NULL, mcid = NULL, direction = c("increase", "decrease") ) ## S3 method for class 'responder_classification' summary(object, ...)classifyResponder( baseline, followup, instrument = NULL, population = NULL, mdc = NULL, mcid = NULL, direction = c("increase", "decrease") ) ## S3 method for class 'responder_classification' summary(object, ...)
baseline, followup
|
Numeric vectors of pre / post scores (one per subject). |
instrument, population
|
Optional instrument / population used to look up
|
mdc, mcid
|
Optional explicit MDC / MCID thresholds (positive); override the store lookup. |
direction |
|
object |
A |
... |
Unused. |
A "responder_classification" data.frame with the change,
the direction-aware improvement, the MDC/MCID crossing flags and the
four-level classification factor. A subject with a missing
baseline/followup gets NA flags and classification
(missing, not assumed a non-responder); summary() counts it.
summary returns the MDC x MCID contingency table.
Beaton DE et al. (2001); de Vet HCW et al. (2006).
estimateMDC(), getClinimetric(), mdcResponder()
classifyResponder(c(20, 25, 30), c(31, 26, 45), mdc = 5.2, mcid = 9)classifyResponder(c(20, 25, 30), c(31, 26, 45), mdc = 5.2, mcid = 9)
Construct a ClinicalInstrument
ClinicalInstrument( id, name = NA_character_, version = NA_character_, items, item_ranges, item_type = "interval", subscales = list(), aggregation = "sum", direction = "higher_better", strata = list(), item_values = list(), item_recode = list(), source_ref = NA_character_ )ClinicalInstrument( id, name = NA_character_, version = NA_character_, items, item_ranges, item_type = "interval", subscales = list(), aggregation = "sum", direction = "higher_better", strata = list(), item_values = list(), item_recode = list(), source_ref = NA_character_ )
id, name, version, items, item_ranges, item_type, subscales, aggregation, direction, strata, item_values, item_recode, source_ref
|
Instrument specification fields (see the class slots). |
A ClinicalInstrument.
scoreInstrument(), registerInstrument()
ClinicalInstrument( id = "toy", name = "Toy scale", items = c("q1", "q2"), item_ranges = list(q1 = c(0, 4), q2 = c(0, 4)))ClinicalInstrument( id = "toy", name = "Toy scale", items = c("q1", "q2"), item_ranges = list(q1 = c(0, 4), q2 = c(0, 4)))
A declarative specification of a clinical outcome measure: its items, their admissible ranges and measurement level, its subscales, how items aggregate into scores, the direction of clinical benefit, and the interpretation strata.
## S4 method for signature 'ClinicalInstrument' show(object)## S4 method for signature 'ClinicalInstrument' show(object)
object |
A |
idShort unique identifier (e.g. "berg").
nameHuman-readable name.
versionSpecification version string.
itemsCharacter vector of item identifiers, in order.
item_rangesNamed list; each entry a length-2 numeric c(min, max) for
the corresponding item.
item_typeCharacter vector (recycled to the item count) of "interval"
or "ordinal".
subscalesNamed list mapping each subscale name to a character vector of its item identifiers; length 0 for single-scale instruments.
aggregation"sum" or "mean".
direction"higher_better" or "higher_worse".
strataList of interpretation bands, each a list with label, lower
and upper.
item_valuesOptional named list; for an item with a discrete (possibly
non-integer) admissible value set - e.g. the Modified Ashworth 1+ = 1.5 -
the numeric vector of allowed values. Items absent from the list are
validated only against item_ranges / item_type.
item_recodeOptional named list; for an item whose raw responses are recoded before scoring (e.g. the SF-36 0-100 recode, or a reversed item), a named numeric map from the raw response (a character key) to the scored value. Applied after validation, before aggregation.
source_refCitation / provenance string.
The result of scoring a set of item responses against a ClinicalInstrument.
## S4 method for signature 'ClinicalScore' show(object)## S4 method for signature 'ClinicalScore' show(object)
object |
A |
instrument_idIdentifier of the scoring instrument.
totalTotal score (or NA if unresolved under the missing policy).
subscalesNamed numeric vector of subscale scores.
stratumInterpretation stratum label the total falls in (or NA).
items_usedCharacter vector of the item identifiers actually scored.
missing_handlingThe missing-data policy applied.
timestampOptional character timestamp.
subject_idOptional subject identifier.
Describes one GAS goal: its attainment levels (typically -2:2 with 0 =
expected outcome), a weight, and an optional ICF linkage. When both
importance and difficulty are given the (Turner-Stokes) weight
is their product; otherwise weight is used (default 1, i.e. unweighted
GAS).
defineGoal( description, levels = -2:2, weight = 1, importance = NULL, difficulty = NULL, icf_tag = NULL )defineGoal( description, levels = -2:2, weight = 1, importance = NULL, difficulty = NULL, icf_tag = NULL )
description |
Free-text goal description. |
levels |
Ordered numeric attainment levels (must include 0, the expected
outcome); default |
weight |
Goal weight when |
importance, difficulty
|
Optional 0+ ratings; if both given the weight is
|
icf_tag |
Optional ICF code (e.g. |
A "gas_goal" object.
Kiresuk & Sherman (1968); Turner-Stokes (2009).
defineGoal("Walk 100 m unaided", importance = 3, difficulty = 2, icf_tag = "d450")defineGoal("Walk 100 m unaided", importance = 3, difficulty = 2, icf_tag = "d450")
Constructs a conversion from a "source" scale to a "target" scale using a linking sample measured on both. Equipercentile equating (the default) maps a source score to the target score with the same percentile rank, so it handles the non-linear, bounded relationship typical of ADL scales; linear equating matches only the mean and SD.
equateScores( from, to, method = c("equipercentile", "linear"), from_scores = sort(unique(from[is.finite(from)])) )equateScores( from, to, method = c("equipercentile", "linear"), from_scores = sort(unique(from[is.finite(from)])) )
from |
Numeric source-scale scores from the linking sample. |
to |
Numeric target-scale scores from the linking sample (equipercentile uses the two marginal distributions; linear uses their means and SDs). |
method |
|
from_scores |
Source scores to tabulate (default: the sorted unique observed source scores). |
an object of class score_equating: a list with table
(data.frame from, to), method, and the linking-sample size. Convert
new values with applyEquating().
Kolen MJ, Brennan RL (2004) Test Equating, Scaling, and Linking; Houlden H et al. (2006) Clin Rehabil 20:153-159 (Barthel<->FIM).
set.seed(1) ability <- rnorm(200) barthel <- pmin(100, pmax(0, round((ability + 3) * 16 / 5) * 5)) fim <- pmin(126, pmax(18, round(18 + (ability + 3) * 18))) eq <- equateScores(barthel, fim) # Barthel -> FIM crosswalk head(eq$table)set.seed(1) ability <- rnorm(200) barthel <- pmin(100, pmax(0, round((ability + 3) * 16 / 5) * 5)) fim <- pmin(126, pmax(18, round(18 + (ability + 3) * 18))) eq <- equateScores(barthel, fim) # Barthel -> FIM crosswalk head(eq$table)
Estimates the MCID from change scores anchored to an external improvement
indicator. "roc" returns the change cut-off that maximizes the Youden
index for classifying the anchor; "mean_change" the mean change among
the (minimally) improved; "predictive" the change at which a logistic
model of the anchor crosses probability 0.5.
estimateMCID_anchor( change, anchor, method = c("roc", "mean_change", "predictive"), direction = c("increase", "decrease") )estimateMCID_anchor( change, anchor, method = c("roc", "mean_change", "predictive"), direction = c("increase", "decrease") )
change |
Numeric change scores (follow-up minus baseline). |
anchor |
Improvement indicator aligned to |
method |
|
direction |
|
The MCID estimate (on the change scale).
Jaeschke et al. (1989); Copay et al. (2007).
estimateMDC(), estimateMCID_distribution()
set.seed(1) change <- c(rnorm(50, 1, 2), rnorm(50, 8, 2)) anchor <- rep(c(0, 1), each = 50) estimateMCID_anchor(change, anchor)set.seed(1) change <- c(rnorm(50, 1, 2), rnorm(50, 8, 2)) anchor <- rep(c(0, 1), each = 50) estimateMCID_anchor(change, anchor)
The distribution-based Minimal Clinically Important Difference as a fraction of the baseline standard deviation (Norman et al. 2003: the 0.5 SD rule).
estimateMCID_distribution(baseline_sd, fraction = 0.5)estimateMCID_distribution(baseline_sd, fraction = 0.5)
baseline_sd |
Baseline standard deviation of the outcome. |
fraction |
Fraction of the SD (default 0.5). |
The MCID estimate (fraction * baseline_sd).
Norman GR, Sloan JA, Wyrwich KW (2003). Med Care 41(5).
estimateMDC(), estimateMCID_anchor()
estimateMCID_distribution(baseline_sd = 12)estimateMCID_distribution(baseline_sd = 12)
Estimates the MDC from a test-retest reliability study: the intraclass
correlation gives the reliability, the standard error of measurement is
, and
(delegating to PhysioCore::icc/sem/mdc).
estimateMDC( test_retest, method = "distribution", confidence = 0.95, model = c("twoway", "oneway") )estimateMDC( test_retest, method = "distribution", confidence = 0.95, model = c("twoway", "oneway") )
test_retest |
A subjects-by-occasions numeric matrix (or data.frame) of repeated measurements. |
method |
Estimation method; currently |
confidence |
Confidence level for the MDC (default 0.95). |
model |
ICC model passed to |
A list with mdc, sem, icc and confidence.
Shrout & Fleiss (1979); de Vet et al. (2006).
estimateMCID_distribution(), estimateMCID_anchor()
set.seed(1) base <- rnorm(40, 50, 10) retest <- base + rnorm(40, 0, 3) estimateMDC(cbind(base, retest))set.seed(1) base <- rnorm(40, 50, 10) retest <- base + rnorm(40, 0, 3) estimateMDC(cbind(base, retest))
Parses an HL7 FHIR R4 Observation (as produced by
toFHIRObservation) back into a ClinicalScore,
the import counterpart of the to*/write* exporters. The
instrument_id and each subscale name are recovered from the bundled
LOINC map (reverse code lookup, then display, then the verbatim text); the
total and subscale values come from valueQuantity (a
dataAbsentReason becomes NA); the subject id strips a leading
"Patient/"; and the timestamp comes from effectiveDateTime.
fromFHIR(observation)fromFHIR(observation)
observation |
A FHIR Observation as a list (a |
The round-trip is lossy for three slots that toFHIRObservation
does not serialize: items_used and missing_handling cannot be
recovered, and stratum is re-derived from the total only when the
instrument is registered (via getInstrument), otherwise
NA.
toFHIRObservation, writeFHIRBundle
sc <- scoreInstrument("katz_adl", stats::setNames(rep(1, 6), getInstrument("katz_adl")@items), subject_id = "P01") fromFHIR(toFHIRObservation(sc))@totalsc <- scoreInstrument("katz_adl", stats::setNames(rep(1, 6), getInstrument("katz_adl")@items), subject_id = "P01") fromFHIR(toFHIRObservation(sc))@total
Tabulate a GAS result
gasSummary(object, ...)gasSummary(object, ...)
object |
A |
... |
Unused. |
A data.frame with one row per goal (description, ICF tag,
weight, attained level and its weighted contribution) plus the T-score as an
attribute.
Retrieves a published clinimetric statistic (MDC, MCID, MCII, SEM, ICC, ...) for a measurement instrument from the packaged, provenanced constants store. The return value carries the source reference (DOI, population n, provenance note) so a looked-up threshold is always attributable.
getClinimetric(instrument, statistic, population = NULL)getClinimetric(instrument, statistic, population = NULL)
instrument |
Instrument name (e.g. |
statistic |
One of |
population |
Optional population/context key to disambiguate multiple
rows (e.g. |
A "clinimetric" data.frame of the matching row(s) with
value, CI, method, reference_doi, population_n
and provenance_note; or NA with a warning when nothing (or no
such population) matches.
getClinimetric("10mWT", "MCII") getClinimetric("FMA-UE", "MCID_anchor", population = "chronic_stroke_minimal")getClinimetric("10mWT", "MCII") getClinimetric("FMA-UE", "MCID_anchor", population = "chronic_stroke_minimal")
Retrieve a registered clinical instrument
getInstrument(id)getInstrument(id)
id |
Instrument identifier. |
The ClinicalInstrument.
listInstruments(), registerInstrument()
Retrieve a normative reference from the registry
getNormative(id, version = "latest", root = NULL)getNormative(id, version = "latest", root = NULL)
id |
Artifact identifier. |
version |
Semantic version, or |
root |
Registry root (see |
The stored GovernedNormativeReference.
registerNormative(), listNormative()
Construct a governed normative reference
GovernedNormativeReference( id, modality, metric, version = "1.0.0", provenance = list(), consent = list(), license = list(), governance = list(), strata_vars = character(0), model = list(), n = NA_real_ )GovernedNormativeReference( id, modality, metric, version = "1.0.0", provenance = list(), consent = list(), license = list(), governance = list(), strata_vars = character(0), model = list(), n = NA_real_ )
id, modality, metric
|
Identifying strings. |
version |
Semantic version (default |
provenance, consent, license, governance
|
Governance lists (see
|
strata_vars |
Character vector of stratification variables. |
model |
List holding the normative model (stratified mean/sd table or LMS coefficients). |
n |
Reference sample size. |
A validated GovernedNormativeReference.
registerNormative(), validateNormativeManifest()
GovernedNormativeReference( id = "gait_speed_adult", modality = "gait", metric = "gait_speed", version = "1.0.0", provenance = list(source = "Bohannon 1997", doi = "10.1093/ageing/26.1.15"), consent = list(status = "public_aggregate"), license = list(spdx = "CC-BY-4.0", redistribution_ok = TRUE), governance = list(custodian = "Matsui Lab", access_level = "open"), strata_vars = c("age", "sex"), model = list(type = "strata", table = data.frame(age = 70, sex = "M", mean = 1.3, sd = 0.2)), n = 230)GovernedNormativeReference( id = "gait_speed_adult", modality = "gait", metric = "gait_speed", version = "1.0.0", provenance = list(source = "Bohannon 1997", doi = "10.1093/ageing/26.1.15"), consent = list(status = "public_aggregate"), license = list(spdx = "CC-BY-4.0", redistribution_ok = TRUE), governance = list(custodian = "Matsui Lab", access_level = "open"), strata_vars = c("age", "sex"), model = list(type = "strata", table = data.frame(age = 70, sex = "M", mean = 1.3, sd = 0.2)), n = 230)
An S4 container for a normative reference distribution together with the governance metadata a clinical artifact must carry: provenance, consent, license and custodianship. Validity requires the provenance source, consent status and license identifier to be present, so an ungoverned reference cannot be constructed.
idStable artifact identifier.
modalitySignal modality (e.g. "gait", "hrv").
metricThe normed quantity (e.g. "gait_speed").
versionSemantic version string "x.y.z".
provenanceList with at least source; optionally doi,
collection_date.
consentList with at least status; optionally ethics_id.
licenseList with at least spdx; optionally
redistribution_ok.
governanceList with custodian and access_level.
strata_varsCharacter vector of stratification variables (e.g.
c("age", "sex")).
modelList holding the normative model — either a stratified
mean/sd table or LMS (lambda/mu/sigma) coefficients.
nReference sample size.
List available clinimetric constants
listClinimetrics(instrument = NULL)listClinimetrics(instrument = NULL)
instrument |
Optional instrument to filter by (case insensitive). |
A data.frame of the stored clinimetric constants.
listClinimetrics("6MWT")listClinimetrics("6MWT")
List available clinical instruments
listInstruments()listInstruments()
A character vector of registered instrument ids.
getInstrument(), registerInstrument()
List registered normative references
listNormative(root = NULL)listNormative(root = NULL)
root |
Registry root (see |
A data.frame of id, version, modality,
metric, access_level and n, newest version last.
registerNormative(), getNormative()
The inverse of the MAS arithmetic mapping: returns the ordinal label for a
numeric MAS value (so 1.5 round-trips to "1+").
masLevelLabel(value)masLevelLabel(value)
value |
Numeric MAS value(s). |
Character MAS level label(s).
masLevelLabel(1.5)masLevelLabel(1.5)
Selects the row of a governed normative reference's model table that matches the supplied covariates: categorical stratification variables (e.g. sex) are matched exactly, numeric ones (e.g. age, speed) by nearest value. A covariate falling outside the tabulated range is flagged as an extrapolation.
matchStratum(ref, covariates)matchStratum(ref, covariates)
ref |
|
covariates |
Named list of covariate values covering the reference's
|
A one-row data.frame (the matched stratum) with an
"extrapolation" attribute (logical).
normativeZScore(), normativeDeviation()
ref <- GovernedNormativeReference("gs", "gait", "gait_speed", provenance = list(source = "x"), consent = list(status = "public"), license = list(spdx = "CC0-1.0"), governance = list(custodian = "lab", access_level = "open"), strata_vars = c("age", "sex"), model = list(type = "strata", table = data.frame( age = c(60, 70), sex = "M", mean = c(1.4, 1.3), sd = 0.2))) matchStratum(ref, list(age = 68, sex = "M"))ref <- GovernedNormativeReference("gs", "gait", "gait_speed", provenance = list(source = "x"), consent = list(status = "public"), license = list(spdx = "CC0-1.0"), governance = list(custodian = "lab", access_level = "open"), strata_vars = c("age", "sex"), model = list(type = "strata", table = data.frame( age = c(60, 70), sex = "M", mean = c(1.4, 1.3), sd = 0.2))) matchStratum(ref, list(age = 68, sex = "M"))
A first responder-analysis primitive: a change is a real improvement/decline
only if it exceeds the MDC (measurement noise). Uses PhysioCore::mdc.
mdcResponder(change, sem_value, confidence = 0.95)mdcResponder(change, sem_value, confidence = 0.95)
change |
Numeric change score(s) (follow-up minus baseline). |
sem_value |
The standard error of measurement (see |
confidence |
Confidence level for the MDC (default 0.95). |
Character vector: "improved", "stable", or "declined".
mdcResponder(c(5, 0.5, -6), sem_value = 1.5)mdcResponder(c(5, 0.5, -6), sem_value = 1.5)
Applies normativeZScore to every row of a metric table: each row
supplies a value plus the covariate columns named by the reference's
strata_vars.
normativeDeviation(metric_table, ref, deviation_z = 2)normativeDeviation(metric_table, ref, deviation_z = 2)
metric_table |
A |
ref |
|
deviation_z |
Deviation-flag threshold (see |
metric_table with added z, percentile,
deviation_flag and extrapolation columns.
Standardizes an observed value against a governed normative reference,
selecting the covariate-matched stratum and applying either a Gaussian
(stratified mean/sd model) or the Cole (1990) LMS
transform (LMS model). An unmatched or unsupported stratum raises an error
rather than returning a silent NA.
normativeZScore(value, ref, covariates = list(), deviation_z = 2)normativeZScore(value, ref, covariates = list(), deviation_z = 2)
value |
Numeric observed value. |
ref |
|
covariates |
Named list of covariates (e.g. |
deviation_z |
Absolute z above which |
A list with z, percentile (0-100), deviation_flag
and extrapolation.
Cole TJ (1990). The LMS method for constructing normalized growth standards. Eur J Clin Nutr 44(1), 45-60.
matchStratum(), normativeDeviation()
ref <- GovernedNormativeReference("gs", "gait", "gait_speed", provenance = list(source = "x"), consent = list(status = "public"), license = list(spdx = "CC0-1.0"), governance = list(custodian = "lab", access_level = "open"), strata_vars = "sex", model = list(type = "strata", table = data.frame(sex = "M", mean = 1.3, sd = 0.2))) normativeZScore(1.0, ref, list(sex = "M"))ref <- GovernedNormativeReference("gs", "gait", "gait_speed", provenance = list(source = "x"), consent = list(status = "public"), license = list(spdx = "CC0-1.0"), governance = list(custodian = "lab", access_level = "open"), strata_vars = "sex", model = list(type = "strata", table = data.frame(sex = "M", mean = 1.3, sd = 0.2))) normativeZScore(1.0, ref, list(sex = "M"))
The other official PROMIS scoring path for a full short form: map the summed raw score to a T-score with the instrument's published summed-score-to-T-score table. The table is not bundled - obtain it from the HealthMeasures scoring manual for the specific short form.
promisRawToT(raw, conversion_table)promisRawToT(raw, conversion_table)
raw |
Summed raw score. |
conversion_table |
A data.frame with a |
A list with tscore and se (NA if the table has no se column);
NA with a warning if raw is not in the table.
tab <- data.frame(raw = 4:8, tscore = c(21.5, 30.1, 35.7, 40.2, 44.0)) promisRawToT(6, tab)tab <- data.frame(raw = 4:8, tscore = c(21.5, 30.1, 35.7, 40.2, 44.0)) promisRawToT(6, tab)
Fits a polytomous Rasch model to a cohort's responses on a registered
instrument and returns the psychometric summary that published ADL/IADL
analyses report: the item difficulty hierarchy, category threshold ordering
(with disordered-threshold flags), person and item measures on an interval
(logit) scale, item fit (infit/outfit), person/item separation reliability,
and the raw-score to interval-measure conversion. The Partial Credit Model is
the default (it accommodates the Barthel Index's mixed item lengths); pass
model = "RSM" for a uniform-format scale.
raschAnalyze(instrument, responses, model = c("PCM", "RSM"), ...)raschAnalyze(instrument, responses, model = c("PCM", "RSM"), ...)
instrument |
A ClinicalInstrument or an instrument id (e.g.
|
responses |
A persons x items matrix or data.frame of responses on the
instrument's native scale (see |
model |
|
... |
Passed to |
Requires the suggested package PhysioAppKit (the domain-neutral engine).
The poly_rasch fit (see PhysioAppKit::pcm_measure()) with an added
class clin_rasch and extra fields: instrument (id), item_hierarchy
(items ordered hardest-to-easiest by calibrated location) and recoded
(the category matrix analysed).
raschRecode(), scoreBarthel(), PhysioAppKit::pcm_measure()
set.seed(1) items <- getInstrument("barthel")@items # a small synthetic cohort of weighted Barthel responses resp <- t(replicate(50, { ability <- stats::rnorm(1) vapply(c(2, 1, 1, 2, 2, 2, 2, 3, 3, 2), function(m) c(0, 5, 10, 15)[min(m, max(0, round(ability + m / 2))) + 1], numeric(1)) })) colnames(resp) <- items if (requireNamespace("PhysioAppKit", quietly = TRUE)) { fit <- raschAnalyze("barthel", resp) fit$item_hierarchy }set.seed(1) items <- getInstrument("barthel")@items # a small synthetic cohort of weighted Barthel responses resp <- t(replicate(50, { ability <- stats::rnorm(1) vapply(c(2, 1, 1, 2, 2, 2, 2, 3, 3, 2), function(m) c(0, 5, 10, 15)[min(m, max(0, round(ability + m / 2))) + 1], numeric(1)) })) colnames(resp) <- items if (requireNamespace("PhysioAppKit", quietly = TRUE)) { fit <- raschAnalyze("barthel", resp) fit$item_hierarchy }
Turns a persons x items table of responses on an instrument's native scale
(e.g. the weighted Barthel levels 0/5/10/15) into the consecutive integer
categories 0..m that a Rasch model expects, using the instrument's declared
admissible item_values as the category order.
raschRecode(instrument, responses)raschRecode(instrument, responses)
instrument |
A ClinicalInstrument or an instrument id. |
responses |
A persons x items matrix or data.frame; columns are matched to the instrument's items by name, or taken in the instrument's item order if unnamed. |
An integer matrix of consecutive category codes (0..m per item), with the instrument's item names as columns.
resp <- rbind(c(10, 5, 5, 10, 10, 10, 10, 15, 15, 10), c(5, 0, 0, 5, 5, 5, 5, 10, 5, 0)) colnames(resp) <- getInstrument("barthel")@items raschRecode("barthel", resp)resp <- rbind(c(10, 5, 5, 10, 10, 10, 10, 15, 15, 10), c(5, 0, 0, 5, 5, 5, 5, 10, 5, 0)) colnames(resp) <- getInstrument("barthel")@items raschRecode("barthel", resp)
Classifies each person's change between two occasions using interval (logit)
measures from raschAnalyze() / PhysioAppKit::pcm_measure(). The Rasch
model's own standard errors give a distribution-free standard error of
measurement and hence the Minimal Detectable Change; the pre/post change is
then run through mdcResponder() (reliable change) and, when an MCID on the
logit scale is supplied, classifyResponder() (the MDC x MCID framework).
raschResponder( pre, post, mcid = NULL, confidence = 0.95, direction = c("increase", "decrease") )raschResponder( pre, post, mcid = NULL, confidence = 0.95, direction = c("increase", "decrease") )
pre, post
|
Baseline and follow-up measures: a |
mcid |
Optional MCID on the logit scale; enables the four-level
|
confidence |
Confidence level for the MDC (default 0.95). |
direction |
|
The two occasions must be on a common metric – calibrate the items once and anchor them, or co-calibrate – and the persons must align by row.
a data.frame, one row per person: pre, post, change,
improvement (direction-aware), sem, mdc, reliable_change (from
mdcResponder()) and, if mcid given, classification (from
classifyResponder()). Attributes sem, mdc, mcid record the values used.
raschAnalyze(), mdcResponder(), classifyResponder(),
estimateMDC()
pre <- list(theta = c(0, 0, 0, 0), theta_se = rep(0.3, 4)) post <- list(theta = c(1.5, 0.1, -1.2, 0.05), theta_se = rep(0.3, 4)) raschResponder(pre, post, mcid = 1.0)pre <- list(theta = c(0, 0, 0, 0), theta_se = rep(0.3, 4)) post <- list(theta = c(1.5, 0.1, -1.2, 0.05), theta_se = rep(0.3, 4)) raschResponder(pre, post, mcid = 1.0)
Adds an instrument to the registry, either a ClinicalInstrument object, a parsed-spec list, or the path to a YAML spec file.
registerInstrument(spec, overwrite = FALSE)registerInstrument(spec, overwrite = FALSE)
spec |
A ClinicalInstrument, a spec list, or a path to a |
overwrite |
Replace an existing instrument with the same id? Default
|
Invisibly, the registered ClinicalInstrument.
getInstrument(), listInstruments()
inst <- ClinicalInstrument(id = "toy2", items = c("a", "b"), item_ranges = list(a = c(0, 1), b = c(0, 1))) registerInstrument(inst)inst <- ClinicalInstrument(id = "toy2", items = c("a", "b"), item_ranges = list(a = c(0, 1), b = c(0, 1))) registerInstrument(inst)
Persists a validated GovernedNormativeReference to the registry
at <root>/<id>/<version>.rds, writing a sibling governance
manifest.json. The artifact must pass both object validity and
validateNormativeManifest.
registerNormative(ref, root = NULL, overwrite = FALSE)registerNormative(ref, root = NULL, overwrite = FALSE)
ref |
|
root |
Registry root directory; defaults to the option
|
overwrite |
Overwrite an already-registered version (default
|
The written .rds path, invisibly.
getNormative(), listNormative()
ref <- GovernedNormativeReference("gs", "gait", "gait_speed", provenance = list(source = "x"), consent = list(status = "public"), license = list(spdx = "CC0-1.0"), governance = list(custodian = "lab", access_level = "open")) registerNormative(ref, root = tempfile("norm"))ref <- GovernedNormativeReference("gs", "gait", "gait_speed", provenance = list(source = "x"), consent = list(status = "public"), license = list(spdx = "CC0-1.0"), governance = list(custodian = "lab", access_level = "open")) registerNormative(ref, root = tempfile("norm"))
Compares a measured joint range of motion against the packaged reference angle
(see romReference()) and, when supplied, the contralateral (usually
unaffected) side - the two comparisons clinicians read a goniometry
measurement against.
romNormalcy(measured, joint, motion, contralateral = NULL)romNormalcy(measured, joint, motion, contralateral = NULL)
measured |
Measured range of motion, in degrees. |
joint, motion
|
The joint and motion (case insensitive); must identify a single reference row. |
contralateral |
Optional measured ROM of the other side, in degrees. |
A one-row data.frame (class "rom_normalcy") with reference_deg,
percent_of_normal (NA for an extension-to-neutral motion whose reference
is 0 deg), deficit_vs_reference (reference minus measured) and limited
(measured below reference); plus contralateral_deg,
deficit_vs_contralateral and percent_of_contralateral when a
contralateral value is given.
romNormalcy(100, "knee", "flexion") romNormalcy(100, "knee", "flexion", contralateral = 130)romNormalcy(100, "knee", "flexion") romNormalcy(100, "knee", "flexion", contralateral = 130)
Returns the packaged normal active range-of-motion reference values for the
major peripheral joints (shoulder, elbow, forearm, wrist, hip, knee, ankle).
These are the consensus clinical goniometry reference angles (in degrees) of
the American Academy of Orthopaedic Surgeons, as tabulated by Norkin & White,
Measurement of Joint Motion. They are single reference angles (not a
distribution), so use romNormalcy() for a reference / side-to-side
comparison; for a stratified z-score build a
GovernedNormativeReference() from a cohort dataset and use
normativeZScore().
romReference(joint = NULL, motion = NULL)romReference(joint = NULL, motion = NULL)
joint |
Optional joint to filter by (e.g. |
motion |
Optional motion to filter by (e.g. |
A data.frame with joint, motion, plane, reference_deg and
source.
American Academy of Orthopaedic Surgeons (1965). Joint Motion: Method of Measuring and Recording. Norkin CC, White DJ. Measurement of Joint Motion: A Guide to Goniometry. F.A. Davis.
romNormalcy(), normativeZScore()
romReference("knee") romReference(motion = "flexion")romReference("knee") romReference(motion = "flexion")
Computes comfortable/fast gait speed and its ambulation category, with an
optional normative z-score. Accepts a gait speed directly, a walk time, or a
PhysioMoCap signal-derived result (walk_test_report from
PhysioMoCap::instrumented10mWT or gait_parameters from
PhysioMoCap::calculateGaitParameters).
score10MWT( x = NULL, time_s = NULL, distance = 10, pace = c("comfortable", "fast"), ref = NULL, covariates = list() )score10MWT( x = NULL, time_s = NULL, distance = 10, pace = c("comfortable", "fast"), ref = NULL, covariates = list() )
x |
A gait speed (m/s), a |
time_s |
Walk time in seconds (manual path; speed = |
distance |
Walk distance in metres (default 10). |
pace |
|
ref |
Optional |
covariates |
Covariates (e.g. |
A "performance_test_score" with gait_speed,
ambulation and (if ref) zscore.
Perry et al. (1995); Fritz & Lusardi (2009); Perera et al. (2006).
score10MWT(time_s = 8) # 10 m / 8 s = 1.25 m/s -> community ambulatorscore10MWT(time_s = 8) # 10 m / 8 s = 1.25 m/s -> community ambulator
Reports the walked distance with, when the demographics are supplied, the Enright & Sherrill (1998) predicted distance, percent-predicted and the lower limit of normal (LLN), plus an optional normative z-score.
score6MWT( distance_m, age = NULL, sex = NULL, height_cm = NULL, weight_kg = NULL, ref = NULL, covariates = list() )score6MWT( distance_m, age = NULL, sex = NULL, height_cm = NULL, weight_kg = NULL, ref = NULL, covariates = list() )
distance_m |
Distance walked in 6 minutes (metres). |
age, sex, height_cm, weight_kg
|
Demographics for the Enright reference equation (all four required for the predicted value). |
ref, covariates
|
Optional normative reference / covariates for a z-score. |
A "performance_test_score" with distance, and (when
demographics are given) predicted, percent_predicted,
lln and below_lln.
Enright PL, Sherrill DL (1998). Am J Respir Crit Care Med 158(5), 1384-1387. doi:10.1164/ajrccm.158.5.9710086
score6MWT(450, age = 60, sex = "male", height_cm = 175, weight_kg = 75)score6MWT(450, age = 60, sex = "male", height_cm = 175, weight_kg = 75)
Score the Action Research Arm Test (ARAT)
scoreARAT(items, ...)scoreARAT(items, ...)
items |
Named numeric responses (0-3 per item) for the 19 ARAT items. |
... |
Passed to |
A ClinicalScore with the total (0-57) and the grasp/grip/pinch/ gross-movement subscale scores.
The Barthel Index rates ten basic ADL domains on their conventional weighted scale (steps of 5; transfers and mobility to 15) for a total of 0-100, higher being more independent.
scoreBarthel(items, ...)scoreBarthel(items, ...)
items |
Named numeric responses on the weighted per-item scale
(e.g. |
... |
Passed to |
A ClinicalScore with the total (0-100) and the dependence stratum (total / severe / moderate / slight dependence / independent).
scoreKatz(), scoreLawton(), raschAnalyze()
scoreBarthel(stats::setNames( c(10, 5, 5, 10, 10, 10, 10, 15, 15, 10), getInstrument("barthel")@items))scoreBarthel(stats::setNames( c(10, 5, 5, 10, 10, 10, 10, 15, 15, 10), getInstrument("barthel")@items))
Score the Berg Balance Scale (BBS)
scoreBerg(items, ...)scoreBerg(items, ...)
items |
Named numeric responses (0-4 per item) for the 14 Berg items. |
... |
Passed to |
A ClinicalScore with the total (0-56) and the fall-risk stratum.
Scores the BPI severity (worst / least / average / current pain) and interference (general activity, mood, walking, work, relations, sleep, enjoyment of life) items, each 0-10. Severity and interference are reported as their mean subscale scores (each 0-10, the conventional BPI summaries); the total is the grand mean over all items.
scoreBPI(items, ...)scoreBPI(items, ...)
items |
Named numeric responses (e.g. |
... |
Passed to |
A ClinicalScore whose subscales hold the severity and
interference means.
scorePainNRS(), getInstrument()
scoreBPI(stats::setNames(c(8, 2, 5, 4, 5, 6, 5, 7, 3, 5, 6), getInstrument("bpi")@items))scoreBPI(stats::setNames(c(8, 2, 5, 4, 5, 6, 5, 7, 3, 5, 6), getInstrument("bpi")@items))
Scores a per-subject table of instrument responses into a list of
ClinicalScore objects, each tagged with its subject_id, ready to drive the
FHIR / OMOP / CDISC exporters (writeFHIRBundle(), toOMOP(),
toCDISC_QS()) directly. The subject_col and item columns can come straight
from a cohort's data (e.g. a PhysioCohort subject table joined to captured
responses).
scoreCohort( responses, instrument, subject_col = "subject_id", timestamp_col = NULL, missing = c("error", "prorate", "na") )scoreCohort( responses, instrument, subject_col = "subject_id", timestamp_col = NULL, missing = c("error", "prorate", "na") )
responses |
A data.frame: one row per subject, with a subject-id column and one column per instrument item (columns not matching an item are ignored). |
instrument |
A ClinicalInstrument or an instrument id (resolved via
|
subject_col |
Name of the subject-id column (default |
timestamp_col |
Optional name of a timestamp column stored on each score. |
missing |
Missing-data policy passed to |
A named list (by subject id) of ClinicalScore objects.
scoreInstrument(), writeFHIRBundle(), toOMOP(), toCDISC_QS()
items <- getInstrument("katz_adl")@items resp <- data.frame(subject_id = c("P01", "P02"), stats::setNames(as.data.frame(rbind(rep(1, 6), c(1, 0, 1, 1, 0, 1))), items)) scores <- scoreCohort(resp, "katz_adl") vapply(scores, function(s) s@total, numeric(1))items <- getInstrument("katz_adl")@items resp <- data.frame(subject_id = c("P01", "P02"), stats::setNames(as.data.frame(rbind(rep(1, 6), c(1, 0, 1, 1, 0, 1))), items)) scores <- scoreCohort(resp, "katz_adl") vapply(scores, function(s) s@total, numeric(1))
Sums the five EQ-5D-5L dimension levels (1 = no problems to 5 = extreme problems / unable) to a level-sum score of 5-25, higher indicating worse health. The utility index requires a country-specific value set and is not computed here; the EQ-VAS (0-100) is a separate rating.
scoreEQ5D5L(items, ...)scoreEQ5D5L(items, ...)
items |
Named numeric levels (e.g. |
... |
Passed to |
A ClinicalScore with the level-sum score (5-25).
scoreEQ5D5L(c(mobility = 2, self_care = 1, usual_activities = 2, pain_discomfort = 3, anxiety_depression = 2))scoreEQ5D5L(c(mobility = 2, self_care = 1, usual_activities = 2, pain_discomfort = 3, anxiety_depression = 2))
Score the Functional Assessment Measure (FIM+FAM)
scoreFAM(items, ...)scoreFAM(items, ...)
items |
Named numeric responses (1-7 per item) for the 30 FIM+FAM items. |
... |
Passed to |
A ClinicalScore with the total (30-210) and the combined motor
(16 items) and cognitive (14 items) subscale scores.
Score the Functional Independence Measure (FIM)
scoreFIM(items, ...)scoreFIM(items, ...)
items |
Named numeric responses (1-7 per item) for the 18 FIM items. |
... |
Passed to |
A ClinicalScore with the total (18-126) and subscale scores for the
six FIM domains (self-care, sphincter, transfers, locomotion,
communication, social cognition) plus the combined motor (13 items) and
cognitive (5 items) scores.
scoreFIM(stats::setNames(rep(4, 18), getInstrument("fim")@items))scoreFIM(stats::setNames(rep(4, 18), getInstrument("fim")@items))
Score the Fugl-Meyer Assessment, Lower Extremity (FMA-LE)
scoreFMALE(items, ...)scoreFMALE(items, ...)
items |
Named numeric responses (0-2 per item) for the 17 FMA-LE motor items, or an unnamed vector in the instrument's item order. |
... |
Passed to |
A ClinicalScore with the total (0-34) and the motor and coordination/speed subscale scores.
scoreFMALE(stats::setNames(rep(2, 17), getInstrument("fma_le")@items))scoreFMALE(stats::setNames(rep(2, 17), getInstrument("fma_le")@items))
Score the Fugl-Meyer Assessment, Upper Extremity (FMA-UE)
scoreFMAUE(items, ...)scoreFMAUE(items, ...)
items |
Named numeric responses (0-2 per item) for the 33 FMA-UE motor items, or an unnamed vector in the instrument's item order. |
... |
Passed to |
A ClinicalScore with the total (0-66), the four subscale scores (shoulder/elbow/forearm, wrist, hand, coordination/speed) and the severe/moderate/mild stratum (Woodbury 2013).
scoreARAT(), scoreInstrument()
scoreFMAUE(stats::setNames(rep(2, 33), getInstrument("fma_ue")@items))scoreFMAUE(stats::setNames(rep(2, 33), getInstrument("fma_ue")@items))
Averages the nine FSS statements (each rated 1 = strongly disagree to 7 = strongly agree) to a mean of 1-7. A mean of 4 or more indicates clinically significant fatigue.
scoreFSS(items, ...)scoreFSS(items, ...)
items |
Named numeric responses ( |
... |
Passed to |
A ClinicalScore with the mean (1-7) and the fatigue stratum.
scoreFSS(stats::setNames(c(6, 6, 5, 6, 5, 6, 6, 5, 6), getInstrument("fss")@items))scoreFSS(stats::setNames(c(6, 6, 5, 6, 5, 6, 6, 5, 6), getInstrument("fss")@items))
Computes the standardized GAS T-score across a set of goals given their attained levels:
where is the attained level, the weight and
the assumed inter-goal correlation. All goals at their expected level
() give .
scoreGAS(goals, attained_levels, rho = 0.3)scoreGAS(goals, attained_levels, rho = 0.3)
goals |
A |
attained_levels |
Numeric attained level for each goal (each within that
goal's |
rho |
Assumed inter-goal correlation in |
A "gas_result" with the T-score, per-goal weights/levels and
rho.
Kiresuk & Sherman (1968); Turner-Stokes (2009).
g1 <- defineGoal("Transfers", importance = 3, difficulty = 2) g2 <- defineGoal("Stairs", importance = 2, difficulty = 3) scoreGAS(list(g1, g2), attained_levels = c(1, 0))g1 <- defineGoal("Transfers", importance = 3, difficulty = 2) g2 <- defineGoal("Stairs", importance = 2, difficulty = 3) scoreGAS(list(g1, g2), attained_levels = c(1, 0))
Validates a set of item responses against a ClinicalInstrument, aggregates them into the total and subscale scores under the chosen missing-data policy, and assigns the interpretation stratum.
scoreInstrument( instrument, items, missing = c("error", "prorate", "na"), subject_id = NA_character_, timestamp = NA_character_ )scoreInstrument( instrument, items, missing = c("error", "prorate", "na"), subject_id = NA_character_, timestamp = NA_character_ )
instrument |
A ClinicalInstrument, or an instrument id resolved via
|
items |
A named numeric vector (item id -> response), a one-row data.frame, or an unnamed vector in the instrument's item order. |
missing |
Missing-data policy: |
subject_id |
Optional subject identifier stored on the result. |
timestamp |
Optional timestamp stored on the result. |
ClinicalInstrument, getInstrument()
inst <- ClinicalInstrument( id = "toy", items = c("q1", "q2", "q3"), item_ranges = list(q1 = c(0, 4), q2 = c(0, 4), q3 = c(0, 4))) scoreInstrument(inst, c(q1 = 2, q2 = 3, q3 = 4))inst <- ClinicalInstrument( id = "toy", items = c("q1", "q2", "q3"), item_ranges = list(q1 = c(0, 4), q2 = c(0, 4), q3 = c(0, 4))) scoreInstrument(inst, c(q1 = 2, q2 = 3, q3 = 4))
Six basic ADL activities (bathing, dressing, toileting, transferring, continence, feeding), each scored independent (1) or dependent (0), for a total of 0-6.
scoreKatz(items, ...)scoreKatz(items, ...)
items |
Named numeric responses (0/1 per activity) or an unnamed vector in the instrument's item order. |
... |
Passed to |
A ClinicalScore with the total (0-6) and the impairment stratum.
scoreKatz(c(bathing = 1, dressing = 1, toileting = 1, transferring = 1, continence = 0, feeding = 1))scoreKatz(c(bathing = 1, dressing = 1, toileting = 1, transferring = 1, continence = 0, feeding = 1))
Eight instrumental-ADL domains of independent community living (telephone,
shopping, food preparation, housekeeping, laundry, transportation,
medication, finances), each dichotomised independent (1) / dependent (0),
summed to a 0-8 count. Lawton & Brody define no total-score severity bands,
so the returned stratum is NA.
scoreLawton(items, ...)scoreLawton(items, ...)
items |
Named numeric responses (0/1 per domain) or an unnamed vector in
the instrument's item order. For the abbreviated male version, omit the
food-preparation, housekeeping and laundry items and use |
... |
Passed to |
A ClinicalScore with the total (0-8).
scoreBarthel(), scoreKatz(), raschAnalyze()
scoreLawton(stats::setNames(rep(1, 8), getInstrument("lawton_iadl")@items))scoreLawton(stats::setNames(rep(1, 8), getInstrument("lawton_iadl")@items))
Accepts a MAS rating as its ordinal level label ("0", "1", "1+", "2",
"3", "4") or the equivalent number, mapping "1+" to 1.5 for arithmetic
while preserving the label. Rate one muscle group per call.
scoreMAS(rating, ...)scoreMAS(rating, ...)
rating |
A single MAS level label or number. |
... |
Passed to |
A ClinicalScore whose total is the numeric MAS value; the ordinal
label is recovered with masLevelLabel().
scoreMAS("1+")scoreMAS("1+")
Sums the twenty-one MFIS items (each 0-4) to a total of 0-84 with physical (9-item), cognitive (10-item) and psychosocial (2-item) subscales. A total of 38 or more indicates fatigue.
scoreMFIS(items, ...)scoreMFIS(items, ...)
items |
Named numeric responses ( |
... |
Passed to |
A ClinicalScore with the total (0-84), the three subscale scores and the fatigue stratum.
scoreMFIS(stats::setNames(rep(2, 21), getInstrument("mfis")@items))scoreMFIS(stats::setNames(rep(2, 21), getInstrument("mfis")@items))
Sums the eleven MMSE components (orientation to time and place, registration, attention/calculation, recall, naming, repetition, a three-stage command, reading, writing and figure copying) to a total of 0-30, higher being better cognition.
scoreMMSE(items, ...)scoreMMSE(items, ...)
items |
Named numeric responses giving the points earned on each
component (e.g. |
... |
Passed to |
A ClinicalScore with the total (0-30), the six-domain subscale scores and the impairment stratum (no / mild / severe impairment).
scoreMMSE(stats::setNames(c(5, 5, 3, 5, 3, 2, 1, 3, 1, 1, 1), getInstrument("mmse")@items))scoreMMSE(stats::setNames(c(5, 5, 3, 5, 3, 2, 1, 3, 1, 1, 1), getInstrument("mmse")@items))
Sums the seven MoCA domains (visuospatial/executive, naming, attention,
language, abstraction, delayed recall and orientation) to a total of 0-30. A
total below 26 indicates cognitive impairment. One point is conventionally
added for participants with 12 or fewer years of formal education (total
capped at 30); apply that adjustment to the orientation item (or the total)
before or after scoring as appropriate for your protocol.
scoreMoCA(items, ...)scoreMoCA(items, ...)
items |
Named numeric responses giving the points earned on each domain
(e.g. |
... |
Passed to |
A ClinicalScore with the total (0-30) and the impairment stratum (normal / mild / moderate-severe impairment).
scoreMoCA(stats::setNames(c(5, 3, 6, 3, 2, 5, 6), getInstrument("moca")@items))scoreMoCA(stats::setNames(c(5, 3, 6, 3, 2, 5, 6), getInstrument("moca")@items))
Sums manual muscle-test grades (0 = no contraction to 5 = normal power) for six movements tested bilaterally - shoulder abduction, elbow flexion, wrist extension, hip flexion, knee extension and ankle dorsiflexion - to a total of 0-60, higher being stronger. A total below 48 defines ICU-acquired weakness.
scoreMRCSum(items, ...)scoreMRCSum(items, ...)
items |
Named numeric grades (e.g. |
... |
Passed to |
A ClinicalScore with the total (0-60), the upper-limb / lower-limb / left / right subscale sums and the weakness stratum.
scoreMRCSum(stats::setNames(rep(5, 12), getInstrument("mrc_sum")@items))scoreMRCSum(stats::setNames(rep(5, 12), getInstrument("mrc_sum")@items))
Score the modified Rankin Scale (mRS)
scoreMRS(grade, ...)scoreMRS(grade, ...)
grade |
A single global disability grade, 0-6. |
... |
Passed to |
A ClinicalScore whose total is the grade and whose stratum is the disability label.
scoreMRS(3)scoreMRS(3)
Score the NIH Stroke Scale (NIHSS)
scoreNIHSS(items, ...)scoreNIHSS(items, ...)
items |
Named numeric responses for the 15 NIHSS components (each within its own range). |
... |
Passed to |
A ClinicalScore with the total (0-42) and the severity band (no stroke / minor / moderate / moderate-to-severe / severe).
A single 0-10 pain-intensity rating, banded into the conventional none / mild / moderate / severe strata. An equivalent 0-100 mm Visual Analogue Scale measures the same construct on a wider range.
scorePainNRS(items, ...)scorePainNRS(items, ...)
items |
The pain rating: a length-1 numeric, or a named vector
|
... |
Passed to |
A ClinicalScore with the rating (0-10) and its severity stratum.
scorePainNRS(c(pain_intensity = 6))scorePainNRS(c(pain_intensity = 6))
Estimates the latent trait for a set of item responses under Samejima's graded response model by expected a posteriori (EAP) scoring over a normal quadrature, and reports it on the PROMIS T-score metric (mean 50, SD 10).
scorePROMIS( responses, calibration, quad_points = 61, quad_range = 4, prior_mean = 0, prior_sd = 1 )scorePROMIS( responses, calibration, quad_points = 61, quad_range = 4, prior_mean = 0, prior_sd = 1 )
responses |
Named numeric vector of item responses (category 1..K per
item; |
calibration |
A data.frame with columns |
quad_points, quad_range
|
EAP quadrature: number of nodes and half-width
(nodes span |
prior_mean, prior_sd
|
Normal prior on the latent trait (default standard normal, the PROMIS calibration metric). |
No item parameters are bundled: supply the official PROMIS calibration (slopes and thresholds) from HealthMeasures. Any GRM-scored instrument works with the same function.
A list with theta, se_theta, tscore (50 + 10 * theta),
se_tscore and n_items (items actually scored).
Samejima F (1969). Estimation of latent ability using a response pattern of graded scores. Psychometrika Monograph 17. PROMIS scoring: HealthMeasures, www.healthmeasures.net.
# illustrative calibration (NOT official PROMIS parameters) cal <- data.frame(item = c("i1", "i2", "i3"), a = c(2.4, 1.9, 2.7), b1 = c(-2, -1.5, -1.8), b2 = c(-1, -0.5, -0.7), b3 = c(0.2, 0.1, 0), b4 = c(1.4, 1.2, 1.1)) scorePROMIS(c(i1 = 4, i2 = 5, i3 = 4), cal)# illustrative calibration (NOT official PROMIS parameters) cal <- data.frame(item = c("i1", "i2", "i3"), a = c(2.4, 1.9, 2.7), b1 = c(-2, -1.5, -1.8), b2 = c(-1, -0.5, -0.7), b3 = c(0.2, 0.1, 0), b4 = c(1.4, 1.2, 1.1)) scorePROMIS(c(i1 = 4, i2 = 5, i3 = 4), cal)
Scores the RAND 36-Item Health Survey 1.0: each item's raw response is recoded
to 0-100 (via the instrument's item_recode map) and averaged within its
scale, giving the eight subscale scores (0-100, higher = better health) in the
returned subscales: physical functioning, role-physical, role-emotional,
energy/fatigue, emotional well-being, social functioning, pain and general
health. The health-transition item is not part of the eight scales. The
norm-based T-scores and the PCS/MCS component summaries use proprietary
population weights and are out of scope.
scoreSF36(items, ...)scoreSF36(items, ...)
items |
Named numeric raw responses on the questionnaire's own answer
scales ( |
... |
Passed to |
A ClinicalScore whose subscales hold the eight 0-100 scale scores
(the total is the grand mean over all items, not a standard SF-36 score).
Hays RD, Sherbourne CD, Mazel RM (1993). The RAND 36-Item Health Survey 1.0. Health Econ 2:217-227.
scoreEQ5D5L(), getInstrument()
# all best-health responses -> every subscale scores 100 best <- stats::setNames( c(1, rep(3, 10), rep(2, 7), 1, 1, 1, 1, 6, 6, 1, 1, 6, 6, 1, 6, 5, 5, 1, 5, 1), getInstrument("sf36")@items) scoreSF36(best)@subscales# all best-health responses -> every subscale scores 100 best <- stats::setNames( c(1, rep(3, 10), rep(2, 7), 1, 1, 1, 1, 6, 6, 1, 1, 6, 6, 1, 6, 5, 5, 1, 5, 1), getInstrument("sf36")@items) scoreSF36(best)@subscales
Classifies TUG time against the standard fall-risk cut-offs (< 10 s
normal; >= 13.5 s elevated community-dwelling fall risk, Shumway-Cook
2000; >= 30 s likely dependent, Podsiadlo & Richardson 1991), with an
optional normative z-score.
scoreTUG(x, ref = NULL, covariates = list())scoreTUG(x, ref = NULL, covariates = list())
x |
A TUG time in seconds, or a PhysioMoCap |
ref, covariates
|
Optional normative reference / covariates for a z-score. |
A "performance_test_score" with time, category
and fall_risk (logical, >= 13.5 s).
Podsiadlo & Richardson (1991); Shumway-Cook et al. (2000).
scoreTUG(15) # >= 13.5 s -> elevated fall riskscoreTUG(15) # >= 13.5 s -> elevated fall risk
Score the Wolf Motor Function Test functional-ability scale (WMFT-FAS)
scoreWMFT(fas, ...)scoreWMFT(fas, ...)
fas |
Named numeric responses (0-5 per task) for the 15 functional tasks. |
... |
Passed to |
A ClinicalScore whose total is the mean functional-ability score.
Show a normative reference (surfacing its governance)
## S4 method for signature 'GovernedNormativeReference' show(object)## S4 method for signature 'GovernedNormativeReference' show(object)
object |
object, invisibly.
Restructures a QS domain (or scores) into an ADaM Basic Data Structure
analysis data set (one PARAMCD per test): AVAL/AVALC
carry the numeric/character result and PARCAT1 the questionnaire
category.
toADaM_ADQS(x, ...)toADaM_ADQS(x, ...)
x |
A |
... |
Passed to |
An ADaM BDS data.frame (columns STUDYID,
USUBJID, PARAMCD, PARAM, PARCAT1, AVAL,
AVALC, AVISIT, AVISITN, ADT).
CDISC ADaM Basic Data Structure (BDS).
Maps one or more ClinicalScore objects to a CDISC SDTMIG
Questionnaires (QS) domain data frame: the total and each subscale becomes a
QS record. QSTESTCD/QSTEST/QSCAT come from the packaged
controlled-terminology map (cdisc_ct.csv); an unmapped instrument gets
a sponsor-defined QSTESTCD (upper-cased, forced to start with a letter,
disambiguated against collisions, and truncated to the SDTM 8-character limit)
with a warning. QSTESTCD values in the shipped map are sponsor-defined
(ct_status = "sponsor"), not asserted to be published CDISC CT.
toCDISC_QS( scores, ct_map = NULL, studyid = "STUDY", usubjid_map = NULL, visitnum = 1L, visit = NA_character_ )toCDISC_QS( scores, ct_map = NULL, studyid = "STUDY", usubjid_map = NULL, visitnum = 1L, visit = NA_character_ )
scores |
A |
ct_map |
Optional data frame overriding the packaged CT map (columns
|
studyid |
|
usubjid_map |
Optional named vector/list mapping |
visitnum, visit
|
|
A QS-domain data.frame conforming to the SDTMIG column layout.
CDISC SDTMIG QS domain.
toADaM_ADQS(), toFHIRObservation(), toOMOP()
sc <- methods::new("ClinicalScore", instrument_id = "fim", total = 90, subscales = c(motor = 60, cognitive = 30), subject_id = "01-001", timestamp = "2026-07-26") toCDISC_QS(sc)sc <- methods::new("ClinicalScore", instrument_id = "fim", total = 90, subscales = c(motor = 60, cognitive = 30), subject_id = "01-001", timestamp = "2026-07-26") toCDISC_QS(sc)
Serializes a ClinicalScore into an HL7 FHIR R4
Observation resource (as a jsonlite-ready list): a survey-category
Observation whose code uses the LOINC map (falling back to a text-only
code), the total as valueQuantity, and each subscale as a
component. Provenance can be attached via derivedFrom.
toFHIRObservation( score, subject = NULL, effectiveDateTime = NULL, derivedFrom = NULL )toFHIRObservation( score, subject = NULL, effectiveDateTime = NULL, derivedFrom = NULL )
score |
|
subject |
Subject reference (e.g. |
effectiveDateTime |
ISO-8601 datetime; defaults to the score's timestamp. |
derivedFrom |
Optional character vector of source references. |
A "fhir_observation" list.
HL7 FHIR R4 Observation; LOINC.
writeFHIRBundle(), validateFHIRObservation()
sc <- methods::new("ClinicalScore", instrument_id = "berg", total = 45, subject_id = "P01", timestamp = "2026-07-26T09:00:00Z") toFHIRObservation(sc)sc <- methods::new("ClinicalScore", instrument_id = "berg", total = 45, subject_id = "P01", timestamp = "2026-07-26T09:00:00Z") toFHIRObservation(sc)
Maps one or more ClinicalScore objects to OMOP Common
Data Model v5.4 MEASUREMENT and OBSERVATION rows. The total and
each subscale become a row, routed to MEASUREMENT or OBSERVATION
by the concept map's domain_id. Concept ids are looked up in the
packaged omop_concept_map.csv; an unmapped instrument yields
measurement_concept_id = 0 (the OMOP "No matching concept") with a
warning. No Athena concept ids are fabricated — the shipped map leaves them
blank; supply a site concept_map to populate them.
toOMOP(scores, concept_map = NULL, person_map = NULL, type_concept_id = 0L)toOMOP(scores, concept_map = NULL, person_map = NULL, type_concept_id = 0L)
scores |
A |
concept_map |
Optional data frame overriding the packaged concept map
(columns |
person_map |
Optional named vector/list mapping |
type_concept_id |
Integer |
A list with MEASUREMENT and OBSERVATION data frames
conforming to the OMOP CDM v5.4 column layout.
OHDSI OMOP CDM v5.4 (MEASUREMENT, OBSERVATION).
writeOMOPTables(), toFHIRObservation()
sc <- methods::new("ClinicalScore", instrument_id = "berg", total = 45, subject_id = "1001", timestamp = "2026-07-26T09:00:00Z") suppressWarnings(toOMOP(sc))sc <- methods::new("ClinicalScore", instrument_id = "berg", total = 45, subject_id = "1001", timestamp = "2026-07-26T09:00:00Z") suppressWarnings(toOMOP(sc))
Validate a FHIR Observation against the bundled JSON schema
validateFHIRObservation(obs)validateFHIRObservation(obs)
obs |
An |
TRUE if valid; otherwise FALSE with the validation
errors as an attribute (requires jsonvalidate).
Checks that a normative reference's manifest carries every required
governance field — a semantic version, and non-empty
provenance$source, consent$status, license$spdx,
governance$custodian and governance$access_level — so an
ungoverned artifact cannot be registered or distributed.
validateNormativeManifest(manifest)validateNormativeManifest(manifest)
manifest |
A manifest list, a |
TRUE invisibly if valid; otherwise an error naming the missing
or invalid fields.
registerNormative(), GovernedNormativeReference()
ref <- GovernedNormativeReference("m", "gait", "gait_speed", provenance = list(source = "x"), consent = list(status = "public"), license = list(spdx = "CC0-1.0"), governance = list(custodian = "lab", access_level = "open")) validateNormativeManifest(ref)ref <- GovernedNormativeReference("m", "gait", "gait_speed", provenance = list(source = "x"), consent = list(status = "public"), license = list(spdx = "CC0-1.0"), governance = list(custodian = "lab", access_level = "open")) validateNormativeManifest(ref)
Summarises the Wolf Motor Function Test timed-task performance as the median time across tasks, the conventional WMFT time summary.
wmftMedianTime(times)wmftMedianTime(times)
times |
Numeric vector of per-task performance times (seconds). |
The median time (seconds).
Write a FHIR Bundle of clinical-score Observations
writeFHIRBundle(scores, path)writeFHIRBundle(scores, path)
scores |
A |
path |
Output |
path, invisibly.
Writes each non-empty table from toOMOP() to <path>/<table>.csv
(lower-cased, e.g. measurement.csv), following the one-file-per-table
OMOP convention.
writeOMOPTables(tables, path)writeOMOPTables(tables, path)
tables |
A |
path |
Output directory (created if needed). |
A character vector of written file paths, invisibly.