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.
Recent studies [1–3] 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 [4–6] require the absence of relapses within appropriate intervals anchored to the dates of three main checkpoints:
For example, in [4], 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 [5], the authors required an absence of relapses during the 90 days before the event and between the event and the confirmation visit; in [6], 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 [7], 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:
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).2
Figure 1. Relapse-free intervals characterising PIRA, as defined by
arguments p0, p1, e0,
e1, c0, c1.
Some examples are provided below.
No relapses during the 90 days before and 30 days after the event, and during the 90 days before and 30 days after confirmation [6]:
relapse_indep <- relapse_indep_from_bounds(p0=0, p1=0, # baseline
e0=90, e1=30, # event
c0=90, c1=30) # confirmationFigure 2. Relapse-free intervals as recommended in [6].
No relapses in the whole period between reference and confirmation [6]:
relapse_indep <- relapse_indep_from_bounds(p0=0, p1=NULL, # baseline
e0=NULL, e1=NULL, # event
c0=NULL, c1=0) # confirmationFigure 3. Relapse-free intervals as recommended in [6] for high specificity.
No relapses between the reference visit and 30 days after the event, and during the 30 days before and 30 days after confirmation [4]:
relapse_indep <- relapse_indep_from_bounds(p0=0, p1=NULL, # baseline
e0=NULL, e1=30, # event
c0=30, c1=30) # confirmationFigure 4. Relapse-free intervals as used in [4].
No relapses during the 90 days before the event and between the event and the confirmation visit [5]:
relapse_indep <- relapse_indep_from_bounds(p0=0, p1=0, # baseline
e0=90, e1=NULL, # event
c0=NULL, c1=0) # confirmationFigure 5. Relapse-free intervals as used in [5].
No relapses since the last visit preceding the event (up to the event) [7]:
relapse_indep <- relapse_indep_from_bounds(p0=0, p1=NULL, # last visit before the event
e0=NULL, e1=0, # event
prec_type='last') Figure 6. Relapse-free intervals as recommended in [7].
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 [6] (baseline='roving' in
MSprog()); or a re-baseline after the onset of each
relapse, as in [4] (relapse_rebl=TRUE in
MSprog()); or both, as in [7].
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)
#> # A tibble: 6 × 5
#> id date visit_day EDSS SDMT
#> <chr> <date> <dbl> <dbl> <dbl>
#> 1 1 2021-09-23 0 5.5 54
#> 2 1 2021-11-03 41 5.5 54
#> 3 1 2022-01-19 118 5.5 57
#> 4 1 2022-04-27 216 5.5 55
#> 5 1 2022-07-12 292 6 57
#> 6 1 2022-11-06 409 6 51
head(toydata_relapses)
#> # A tibble: 5 × 3
#> id date visit_day
#> <chr> <date> <dbl>
#> 1 2 2021-06-12 198
#> 2 2 2022-10-25 698
#> 3 3 2022-12-01 409
#> 4 6 2022-12-18 426
#> 5 7 2021-09-11 185The 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.
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 [6]:
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)
#>
#> Subject #1: 8 visits, 0 relapses
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.5 (2022-07-12); potential confirmation visits available: no.6, 7, 8
#> Found EDSS-CDW (PIRA) (visit no.5, 2022-07-12) confirmed at 84 days, sustained up to visit no.8 (2023-03-11)
#> Baseline at visit no.6
#> event="firstPIRA" already found: end process
#> Event: PIRA
#>
#> Subject #2: 10 visits, 2 relapses
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.4 (2021-06-12); potential confirmation visits available: no.5, 6, 7, 8, 9, 10
#> Found EDSS-CDW (RAW) (visit no.4, 2021-06-12) confirmed at 84 days, sustained up to visit no.5 (2021-09-04)
#> Baseline at visit no.5
#> Searching for events from visit no.6 on
#> Found EDSS change at visit no.8 (2022-05-19); potential confirmation visits available: no.9, 10
#> Found EDSS-CDW (PIRA) (visit no.8, 2022-05-19) confirmed at 84 days, sustained up to visit no.10 (2022-11-26)
#> Baseline at visit no.9
#> event="firstPIRA" already found: end process
#> Event: PIRA
#>
#> Subject #3: 7 visits, 1 relapse
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.2 (2021-12-01); potential confirmation visits available: no.4, 5, 7
#> Not a confirmed change: proceed with search
#> Searching for events from visit no.3 on
#> No edss change in any subsequent visit: end process
#> Event: -
#>
#> Subject #4: 7 visits, 0 relapses
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.2 (2021-12-04); potential confirmation visits available: no.3, 4, 5, 6, 7
#> Found EDSS-CDI (visit no.2, 2021-12-04) confirmed at 84 days, sustained up to visit no.3 (2022-03-12)
#> Baseline at visit no.3
#> Searching for events from visit no.4 on
#> Found EDSS change at visit no.4 (2022-07-19); potential confirmation visits available: no.6, 7
#> Found EDSS-CDW (PIRA) (visit no.4, 2022-07-19) confirmed at 84 days, sustained up to visit no.7 (2023-04-27)
#> Baseline at visit no.6
#> event="firstPIRA" already found: end process
#> Event: PIRA
#>
#> Subject #5: 9 visits, 0 relapses
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.3 (2021-11-01); potential confirmation visits available: no.5, 6, 7, 8, 9
#> Found EDSS-CDW (PIRA) (visit no.3, 2021-11-01) confirmed at 84 days, sustained up to visit no.9 (2023-03-13)
#> Baseline at visit no.5
#> event="firstPIRA" already found: end process
#> Event: PIRA
#>
#> Subject #6: 7 visits, 1 relapse
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.3 (2022-02-15); potential confirmation visits available: no.4, 5, 7
#> Found EDSS-CDI (visit no.3, 2022-02-15) confirmed at 84 and 168 days, sustained up to visit no.5 (2022-10-05)
#> Baseline at visit no.4
#> Searching for events from visit no.5 on
#> Found EDSS change at visit no.6 (2022-12-22); potential confirmation visits available: no.
#> Not a confirmed change: proceed with search
#> Searching for events from visit no.7 on
#> Found EDSS change at visit no.7 (2023-02-21); potential confirmation visits available: no.
#> Not a confirmed change: proceed with search
#> Searching for events from visit no.- on
#> No edss change in any subsequent visit: end process
#> Event: -
#>
#> Subject #7: 9 visits, 1 relapse
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.3 (2021-09-11); potential confirmation visits available: no.5, 6, 7, 8, 9
#> Not a confirmed change: proceed with search
#> Searching for events from visit no.4 on
#> Found EDSS change at visit no.5 (2022-03-17); potential confirmation visits available: no.6, 7, 8, 9
#> Found EDSS-CDW (PIRA) (visit no.5, 2022-03-17) confirmed at 84 days, sustained up to visit no.9 (2023-04-28)
#> Baseline at visit no.6
#> event="firstPIRA" already found: end process
#> Event: PIRA
#>
#> ---
#> Outcome: edss
#> Confirmation over: 84, 168 days (-0 days, +Inf days)
#> Baseline: roving
#> Baseline skipped if: <30 days from last relapse
#> Event skipped if: -
#> Confirmation visit skipped if: <30 days from last relapse
#> Events detected: firstPIRA
#>
#> *Please use `print(output)` to display full info on event detection criteria*
#>
#> ---
#> Total subjects: 7
#> ---
#> Subjects with PIRA: 5
# print(output$results, row.names=FALSE) # results
DT::datatable(output$results, rownames=F,
options = list(dom='t', scrollX=T, scrollY="200px", paging = FALSE)
)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 [4]:
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)
#>
#> Subject #1: 8 visits, 0 relapses
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.5 (2022-07-12); potential confirmation visits available: no.6, 7, 8
#> Found EDSS-CDW (PIRA) (visit no.5, 2022-07-12) confirmed at 84 days, sustained up to visit no.8 (2023-03-11)
#> event="firstPIRA" already found: end process
#> Event: PIRA
#>
#> Subject #2: 10 visits, 2 relapses
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.4 (2021-06-12); potential confirmation visits available: no.5, 6, 7, 8, 9, 10
#> Searching for events from visit no.5 on
#> [post-relapse rebaseline] Baseline moved to visit no.4
#> Baseline (visit no.4) is within relapse influence: moved to visit no.5
#> Searching for events from visit no.6 on
#> Found EDSS change at visit no.8 (2022-05-19); potential confirmation visits available: no.9, 10
#> Found EDSS-CDW (PIRA) (visit no.8, 2022-05-19) confirmed at 84 days, sustained up to visit no.10 (2022-11-26)
#> [post-relapse rebaseline] Baseline moved to visit no.10
#> [post-relapse rebaseline] Not enough visits after current baseline: end process
#> Event: PIRA
#>
#> Subject #3: 7 visits, 1 relapse
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.2 (2021-12-01); potential confirmation visits available: no.4, 5, 7
#> Not a confirmed PIRA: proceed with search
#> Searching for events from visit no.3 on
#> No edss change in any subsequent visit: end process
#> Event: -
#>
#> Subject #4: 7 visits, 0 relapses
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.2 (2021-12-04); potential confirmation visits available: no.3, 4, 5, 6, 7
#> Not a confirmed PIRA: proceed with search
#> Searching for events from visit no.3 on
#> Found EDSS change at visit no.3 (2022-03-12); potential confirmation visits available: no.4, 5, 6, 7
#> Not a confirmed PIRA: proceed with search
#> Searching for events from visit no.4 on
#> Found EDSS change at visit no.6 (2023-01-16); potential confirmation visits available: no.7
#> Not a confirmed PIRA: proceed with search
#> Searching for events from visit no.7 on
#> No edss change in any subsequent visit: end process
#> Event: -
#>
#> Subject #5: 9 visits, 0 relapses
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.3 (2021-11-01); potential confirmation visits available: no.5, 6, 7, 8, 9
#> Found EDSS-CDW (PIRA) (visit no.3, 2021-11-01) confirmed at 84 days, sustained up to visit no.9 (2023-03-13)
#> event="firstPIRA" already found: end process
#> Event: PIRA
#>
#> Subject #6: 7 visits, 1 relapse
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.3 (2022-02-15); potential confirmation visits available: no.4, 5, 7
#> Not a confirmed PIRA: proceed with search
#> Searching for events from visit no.4 on
#> Found EDSS change at visit no.4 (2022-09-03); potential confirmation visits available: no.7
#> Not a confirmed PIRA: proceed with search
#> Searching for events from visit no.5 on
#> Found EDSS change at visit no.5 (2022-10-05); potential confirmation visits available: no.7
#> Not a confirmed PIRA: proceed with search
#> [post-relapse rebaseline] Baseline moved to visit no.6
#> Baseline (visit no.6) is within relapse influence: moved to visit no.7
#> Not enough visits left: end process
#> Searching for events from visit no.- on
#> No edss change in any subsequent visit: end process
#> Event: -
#>
#> Subject #7: 9 visits, 1 relapse
#> Baseline at visit no.1
#> Searching for events from visit no.2 on
#> Found EDSS change at visit no.3 (2021-09-11); potential confirmation visits available: no.5, 6, 7, 8, 9
#> Not a confirmed PIRA: proceed with search
#> [post-relapse rebaseline] Baseline moved to visit no.3
#> Baseline (visit no.3) is within relapse influence: moved to visit no.4
#> Searching for events from visit no.5 on
#> Found EDSS change at visit no.5 (2022-03-17); potential confirmation visits available: no.6, 7, 8, 9
#> Found EDSS-CDW (PIRA) (visit no.5, 2022-03-17) confirmed at 84 days, sustained up to visit no.9 (2023-04-28)
#> event="firstPIRA" already found: end process
#> Event: PIRA
#>
#> ---
#> Outcome: edss
#> Confirmation over: 84, 168 days (-0 days, +Inf days)
#> Baseline: fixed, and post-relapse re-baseline
#> Baseline skipped if: <30 days from last relapse
#> Event skipped if: -
#> Confirmation visit skipped if: <30 days from last relapse
#> Events detected: firstPIRA
#>
#> *Please use `print(output)` to display full info on event detection criteria*
#>
#> ---
#> Total subjects: 7
#> ---
#> Subjects with PIRA: 4
# 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.
if skip_local_extrema is not
"none" in msprog::MSprog(), local extrema are
excluded from (iii).↩︎
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.↩︎