Assessing progression independent of relapse activity (PIRA) in MS

knitr::opts_chunk$set(
  collapse=TRUE,
  comment="#>"
)

This vignette illustrates how to use the msprog package to study disability progression independent of relapse activity (PIRA) in multiple sclerosis (MS). For a more general introduction on msprog package usage for disability course assessment, please refer to the vignette Analysing disability course in MS.

library(msprog)

Defining PIRA

Recent studies [@kappos2018; @silent2019; @kuhlmann2023] have highlighted the contribution of PIRA to overall disability worsening, generating growing interest in PIRA as a relevant endpoint. Classifying a confirmed disability worsening (CDW) event as relapse-independent requires careful observation of its relative timing with respect to relapses. Established definitions of PIRA [@kappos2020; @cagol2022; @muller2023] require the absence of relapses within appropriate intervals anchored to the dates of three main checkpoints:

  1. a visit preceding the event: can be (i) the current reference, (ii) the last visit before event onset, or (iii) the last visit before event onset with a clinically meaningful score distance from it [^extrema];
  2. the initial disability worsening (event onset);
  3. an eligible confirmation visit.

[^extrema]: if skip_local_extrema is not "none" in msprog::MSprog(), local extrema are excluded from (iii).

For example, in @kappos2020, an absence of relapses was required between the reference visit and 30 days after the event, and during the 30 days before and 30 days after confirmation for a CDW event to be considered as PIRA; in @cagol2022, the authors required an absence of relapses during the 90 days before the event and between the event and the confirmation visit; in @muller2023, the authors recommend an absence of relapses during the 90 days before and 30 days after the event, and during the 90 days before and 30 days after confirmation; when a high specificity is desired, they recommend an absence of relapses in the whole period between reference and confirmation; in @muller2025, the authors recommend an absence of relapses since the last visit preceding the event (up to the event), and during the 30 days before confirmation.

Such an approach is easily integrated into the msprog::MSprog() function through its argument relapse_indep, allowing to specify custom relapse-free intervals based on any subset of the checkpoints 1-3, thus allowing to replicate any of the above-mentioned definitions. The relapse_indep argument must be provided in the form produced by function msprog::relapse_indep_from_bounds(), as follows: ``` {r, eval=FALSE} output <- MSprog(... relapse_indep=relapse_indep_from_bounds(p0, p1, e0, e1, c0, c1, prec_type, use_end_dates), ...)

where: `p0` and `p1` specify the interval around the preceding visit; `e0` and `e1` specify the interval around the event; `c0` and `c1` specify the interval around the confirmation visit; see Figure 1. If both ends of an interval are 0 (e.g., if both `p0=0` and `p1=0`), the checkpoint is ignored. To merge two intervals together, set both the right end of the first interval and the left end of the second interval to `NULL` (e.g., "between baseline and event onset": `p1=NULL` and `e0=NULL`). The `prec_type` argument specifies which preceding visit to take into account (`'baseline'` for current reference, `'last'` for last visit preceding event onset, `'last_delta'` for last visit preceding event onset with a clinically meaningful score distance from it).[^enddates]

[^enddates]: If **end dates** of relapses are available (may be provided as an additional column in the relapse file whose name is specified by argument `renddate_col` in `MSprog()`), the `use_end_dates` argument in `relapse_indep_from_bounds()` controls whether they are used for PIRA or not. The default is `use_end_dates=F`. If `use_end_dates=T`, the provided intervals are ignored and PIRA is defined by the event or the confirmation not falling within the duration (onset to end) of a relapse. 

```r
knitr::include_graphics('./relapse_indep_def.png')


Some examples are provided below.

r knitr::include_graphics('./relapse_indep_rev1.png')

r knitr::include_graphics('./relapse_indep_rev0.png')

r knitr::include_graphics('./relapse_indep_kappos.png')

r knitr::include_graphics('./relapse_indep_cagol.png')

r knitr::include_graphics('./relapse_indep_muller2025.png')

The requirement of relapse-free periods is often coupled with a non-fixed baseline scheme. This can be a roving baseline, where the reference value is updated after every confirmed improvement or worsening event, as in @muller2023 (baseline='roving' in MSprog()); or a re-baseline after the onset of each relapse, as in @kappos2020 (relapse_rebl=TRUE in MSprog()); or both, as in @muller2025.

Detecting PIRA

To illustrate how to apply the above definitions when assessing disability course from patient data, we use the toy data provided in the msprog package. These include artificially generated EDSS and SDMT assessments (toydata_visits) and relapse dates (toydata_relapses) for four patients:

head(toydata_visits)
head(toydata_relapses)


The following code detects, for each subject in the toy dataset, the first EDSS PIRA event (event='firstPIRA') confirmed over $\geq$ 12 or $\geq$ 24 weeks (conf_days=c(7*12, 7*24), conf_tol_days=c(0, Inf)), for two different definitions of PIRA. We set verbose=2 to print an extended log of the computations performed.

  1. Roving baseline, and absence of relapses during the 90 days before and 30 days after the event, and during the 90 days before and 30 days after confirmation @muller2023:
output <- MSprog(toydata_visits, 'id', 'EDSS', 'date', 'edss',
               relapse=toydata_relapses, 
               conf_days=c(7*12, 7*24), conf_tol_days=c(0, Inf),
               event='firstPIRA', baseline='roving',
               relapse_indep=relapse_indep_from_bounds(p0=0, p1=0, e0=90, e1=30, c0=90, c1=30),
               verbose=2)
# print(output$results, row.names=FALSE) # results
DT::datatable(output$results, rownames=F,
              options = list(dom='t', scrollX=T, scrollY="200px", paging = FALSE)
              )
<br>
  1. Post-relapse re-baseline, and absence of relapses between the reference visit and 30 days after the event, and during the 30 days before and 30 days after confirmation @kappos2020:
output <- MSprog(toydata_visits, 'id', 'EDSS', 'date', 'edss',
               relapse=toydata_relapses,
               conf_days=c(7*12, 7*24), conf_tol_days=c(0, Inf), 
               event='firstPIRA', baseline='fixed', relapse_rebl=TRUE,
               relapse_indep=relapse_indep_from_bounds(p0=0, p1=NULL, e0=NULL, e1=30, c0=30, c1=30),
               verbose=2)
# print(output$results, row.names=FALSE) # results
DT::datatable(output$results, rownames=F,
              options = list(dom='t', scrollX=T, scrollY="200px", paging = FALSE)
              )

Here, nevent is the cumulative event count for each subject, and event_type characterises the event (since event is set to firstPIRA, the count is either 0 or 1 and the event type, when present, is always PIRA); time2event is the number of days from start of follow-up to event; bl2event is the number of days from current baseline to event; conf84 and conf168 report whether the event was confirmed as a CDW over 12 or 24 weeks (84 or 168 days); PIRAconf84 and PIRAconf168 report whether the event was confirmed as PIRA over 12 or 24 weeks (84 or 168 days); sust_days is the number of days for which the event was sustained; sust_last reports whether the event was sustained until the last visit.

References



Try the msprog package in your browser

Any scripts or data that you put into this service are public.

msprog documentation built on Sept. 4, 2026, 5:08 p.m.