Simulate outcomes from an individual-level continuous time state transition
model (CTSTM). The class supports "clock-reset"
(i.e., semi-Markov), "clock-forward" (i.e., Markov), and mixtures of
clock-reset and clock-forward multi-state models as described in
`IndivCtstmTrans`

.

An R6::R6Class object.

Incerti and Jansen (2021). See Section 2.2 for a mathematical description of an individual-level CTSTM and Section 4.1 for an example in oncology.

The `IndivCtstmTrans`

documentation
describes the class for the transition model and the `StateVals`

documentation
describes the class for the cost and utility models. An `IndivCtstmTrans`

object is typically created using `create_IndivCtstmTrans()`

.

There are currently two relevant vignettes. `vignette("mstate")`

shows how to
parameterize `IndivCtstmTrans`

objects in cases where patient-level data is
available by fitting a multi-state models. `vignette("markov-inhomogeneous-indiv")`

shows how the time inhomogeneous Markov cohort model in
`vignette("markov-inhomogeneous-cohort")`

can be developed as an individual
patient simulation; in doing so, it shows how `IndivCtstm`

models can be
used even without access to patient-level data.

`trans_model`

The model for health state transitions. Must be an object of class

`IndivCtstmTrans`

.`utility_model`

The model for health state utility. Must be an object of class

`StateVals`

.`cost_models`

The models used to predict costs by health state. Must be a list of objects of class

`StateVals`

, where each element of the list represents a different cost category.`disprog_`

An object of class

`disprog`

.`stateprobs_`

An object of class

`stateprobs`

simulated using`$sim_stateprobs()`

.`qalys_`

An object of class

`qalys`

simulated using`$sim_qalys()`

.`costs_`

An object of class

`costs`

simulated using`$sim_costs()`

.

`new()`

Create a new `IndivCtstm`

object.

`IndivCtstm$new(trans_model = NULL, utility_model = NULL, cost_models = NULL)`

`sim_disease()`

Simulate disease progression (i.e., individual trajectories through a multi-state
model) using `IndivCtstmTrans$sim_disease()`

.

`max_t`

A scalar or vector denoting the length of time to simulate the model. If a vector, must be equal to the number of simulated patients.

`max_age`

A scalar or vector denoting the maximum age to simulate each patient until. If a vector, must be equal to the number of simulated patients.

`progress`

An integer, specifying the PSA iteration (i.e., sample) that should be printed every

`progress`

PSA iterations. For example, if`progress = 2`

, then every second PSA iteration is printed. Default is`NULL`

, in which case no output is printed.

`sim_stateprobs()`

Simulate health state probabilities as a function of time using the
simulation output stored in `disprog`

.

An instance of `self`

with simulated output of class `stateprobs`

stored in `stateprobs_`

.

`sim_qalys()`

Simulate quality-adjusted life-years (QALYs) as a function of `disprog_`

and
`utility_model`

.

```
IndivCtstm$sim_qalys(
dr = 0.03,
type = c("predict", "random"),
lys = TRUE,
by_patient = FALSE
)
```

`dr`

Discount rate.

`type`

`"predict"`

for mean values or`"random"`

for random samples as in`$sim()`

in`StateVals`

.`lys`

If

`TRUE`

, then life-years are simulated in addition to QALYs.`by_patient`

If

`TRUE`

, then QALYs and/or costs are computed at the patient level. If`FALSE`

, then they are averaged across patients by health state.

An instance of `self`

with simulated output of
class qalys stored in `qalys_`

.

`sim_costs()`

Simulate costs as a function of `disprog_`

and `cost_models`

.

```
IndivCtstm$sim_costs(
dr = 0.03,
type = c("predict", "random"),
by_patient = FALSE,
max_t = Inf
)
```

`dr`

Discount rate.

`type`

`"predict"`

for mean values or`"random"`

for random samples as in`$sim()`

in`StateVals`

.`by_patient`

If

`TRUE`

, then QALYs and/or costs are computed at the patient level. If`FALSE`

, then they are averaged across patients by health state.`max_t`

Maximum time duration to compute costs once a patient has entered a (new) health state. By default, equal to

`Inf`

, so that costs are computed over the entire duration that a patient is in a given health state. If time varies by each cost category, then time can also be passed as a numeric vector of length equal to the number of cost categories (e.g.,`c(1, 2, Inf, 3)`

for a model with four cost categories).

An instance of `self`

with simulated output of class costs
stored in `costs_`

.

`summarize()`

Summarize costs and QALYs so that cost-effectiveness analysis can be performed.
See `summarize_ce()`

.

```
library("flexsurv")
#> Loading required package: survival
#>
#> Attaching package: ‘flexsurv’
#> The following object is masked from ‘package:msm’:
#>
#> qgeneric
# Treatment strategies, target population, and model structure
strategies <- data.frame(strategy_id = c(1, 2))
patients <- data.frame(patient_id = seq(1, 3),
age = c(45, 50, 60),
female = c(0, 0, 1))
states <- data.frame(state_id = c(1, 2))
hesim_dat <- hesim_data(strategies = strategies,
patients = patients,
states = states)
# Parameter estimation
## Multi-state model
tmat <- rbind(c(NA, 1, 2),
c(3, NA, 4),
c(NA, NA, NA))
fits <- vector(length = max(tmat, na.rm = TRUE), mode = "list")
surv_dat <- data.frame(mstate3_exdata$transitions)
for (i in 1:length(fits)){
fits[[i]] <- flexsurvreg(Surv(years, status) ~ factor(strategy_id),
data = surv_dat,
subset = (trans == i),
dist = "weibull")
}
fits <- flexsurvreg_list(fits)
## Utility
utility_tbl <- stateval_tbl(data.frame(state_id = states$state_id,
mean = mstate3_exdata$utility$mean,
se = mstate3_exdata$utility$se),
dist = "beta")
## Costs
drugcost_tbl <- stateval_tbl(data.frame(strategy_id = strategies$strategy_id,
est = mstate3_exdata$costs$drugs$costs),
dist = "fixed")
medcost_tbl <- stateval_tbl(data.frame(state_id = states$state_id,
mean = mstate3_exdata$costs$medical$mean,
se = mstate3_exdata$costs$medical$se),
dist = "gamma")
# Economic model
n_samples = 2
## Construct model
### Transitions
transmod_data <- expand(hesim_dat)
transmod <- create_IndivCtstmTrans(fits, input_data = transmod_data,
trans_mat = tmat,
n = n_samples)
### Utility
utilitymod <- create_StateVals(utility_tbl, n = n_samples, hesim_data = hesim_dat)
### Costs
drugcostmod <- create_StateVals(drugcost_tbl, n = n_samples, hesim_data = hesim_dat)
medcostmod <- create_StateVals(medcost_tbl, n = n_samples, hesim_data = hesim_dat)
costmods <- list(drugs = drugcostmod,
medical = medcostmod)
### Combine
ictstm <- IndivCtstm$new(trans_model = transmod,
utility_model = utilitymod,
cost_models = costmods)
## Simulate outcomes
head(ictstm$sim_disease()$disprog_)
#> sample strategy_id patient_id grp_id from to final time_start
#> <num> <int> <int> <int> <num> <num> <int> <num>
#> 1: 1 1 1 1 1 2 0 0.000000000
#> 2: 1 1 1 1 2 3 1 0.393003227
#> 3: 1 1 2 1 1 2 0 0.000000000
#> 4: 1 1 2 1 2 3 1 1.702282887
#> 5: 1 1 3 1 1 2 0 0.000000000
#> 6: 1 1 3 1 2 1 0 0.003928804
#> time_stop
#> <num>
#> 1: 0.393003227
#> 2: 0.855571106
#> 3: 1.702282887
#> 4: 3.171624306
#> 5: 0.003928804
#> 6: 1.679816476
head(ictstm$sim_stateprobs(t = c(0, 5, 10))$stateprobs_[t == 5])
#> sample strategy_id grp_id state_id t prob
#> <num> <int> <int> <num> <num> <num>
#> 1: 1 1 1 1 5 0.0000000
#> 2: 1 1 1 2 5 0.0000000
#> 3: 1 1 1 3 5 1.0000000
#> 4: 1 2 1 1 5 0.3333333
#> 5: 1 2 1 2 5 0.0000000
#> 6: 1 2 1 3 5 0.6666667
ictstm$sim_qalys(dr = .03)
ictstm$sim_costs(dr = .03)
### Summarize cost-effectiveness
ce <- ictstm$summarize()
head(ce)
#> $costs
#> category dr sample strategy_id costs grp_id
#> <char> <num> <num> <int> <num> <num>
#> 1: drugs 0.03 1 1 10144.883 1
#> 2: drugs 0.03 1 2 38646.339 1
#> 3: drugs 0.03 2 1 27826.855 1
#> 4: drugs 0.03 2 2 33744.345 1
#> 5: medical 0.03 1 1 2707.041 1
#> 6: medical 0.03 1 2 4092.512 1
#> 7: medical 0.03 2 1 6864.213 1
#> 8: medical 0.03 2 2 3551.016 1
#> 9: total 0.03 1 1 12851.924 1
#> 10: total 0.03 1 2 42738.851 1
#> 11: total 0.03 2 1 34691.069 1
#> 12: total 0.03 2 2 37295.361 1
#>
#> $qalys
#> dr sample strategy_id qalys grp_id
#> <num> <num> <int> <num> <num>
#> 1: 0.03 1 1 1.756493 1
#> 2: 0.03 1 2 2.869877 1
#> 3: 0.03 2 1 5.032089 1
#> 4: 0.03 2 2 2.920488 1
#>
format(summary(ce), pivot_from = "strategy")
#> Discount rate Outcome 1 2
#> <num> <fctr> <char> <char>
#> 1: 0.03 QALYs 3.39 (1.84, 4.95) 2.90 (2.87, 2.92)
#> 2: 0.03 Costs: drugs 18,986 (10,587, 27,385) 36,195 (33,867, 38,524)
#> 3: 0.03 Costs: medical 4,786 (2,811, 6,760) 3,822 (3,565, 4,079)
#> 4: 0.03 Costs: total 23,771 (13,398, 34,145) 40,017 (37,431, 42,603)
```