hesim-dev / hesim

Health economic simulation modeling and decision analysis
https://hesim-dev.github.io/hesim/
62 stars 16 forks source link

PSM with costs that vary over time #64

Closed heor-andreas closed 3 years ago

heor-andreas commented 3 years ago

Hi there,

I'm trying to set up a PSM that allows for drug costs to vary over time within the strategy and states. Say in state 1, strategy 1 people receive drug for weeks 1:4 and then switch to less frequent regime.

Is it possible to implement this within the hesim framework?

Thanks Andreas

dincerti commented 3 years ago

Hi Andreas,

PSMs are "area under the curve" models and can therefore be a bit limiting. Costs within a PSM can very over time, but only as a function of time since the start of the model (i.e., not since time since entering an intermediate health state). So if drug costs only vary in state 1, then it is possible. But if drug costs also vary as a function of time in say, state 2, then is is not. You can accomplish this with stateval_tbl(), e.g.,

drugcost_tbl <- stateval_tbl(
  data.frame(strategy_id = rep(c(1, 2), each = 4),
             state_id = rep(c(1, 2, 1, 2), each = 2),
             time_start = rep(c(0, .5, 0, .5), times = 2),
             est = c(5000, 10000, 7000, 7000, # Strategy 1
                         8000, 12000, 9000, 9000) # Strategy 2
  ),
  dist = "fixed"
)

If you want drug costs to vary as a function of time in intermediate states, then you need to use a Markov model with tunnel states or an individual-level simulation. You can use the cohort discrete time state transition models (cDTSTMs) or individual continuous time state transition models (iCTSTMs) for this. In these cases you would need to parameterize the transition model yourself (e.g., transition probability matrices in a cDTSTM); automated parameterization of cDTSTMs in a partitioned survival context is on my to do list but has not yet been implemented unfortunately.

heor-andreas commented 3 years ago

Thanks Devin, that's really great. One more question, if I have a treatment regime that happens every 2 weeks, is there a quick way of doing this or would I have to set up a long table for each week?

Also, can you confirm that the time_start units are the same that I specify as x in sim_survival(t=x)?

heor-andreas commented 3 years ago

Sorry if this is going off topic, but is it possible to include survival data that is only a mean/median OS/PFS? I have seen that with the rcea::sim_pfs_os_data function I can simulate the data, but am wondering what to do if I only have a mean/median survival?

dincerti commented 3 years ago

Hi Andreas,

If your treatment regime happens every 2 weeks, then you would indeed need to setup a long table. The units should be the same as in your survival model, typically its easiest to put everything in years.

If all you have is mean/median OS/PFS, you are limited in what you can do. Your best bet is probably to use an exponential distribution: the rate parameter is 1/mean and log(2)/median. If you have the full curve, you can also digitize it and then reconstruct IPD individual-patient data using published algorithms.

-Devin

heor-andreas commented 3 years ago

Thanks again, Devin, I'm thinking about using an exponential on mean OS/PFS data. Is that something I can do using the hesim framework? From what I've seen I can use flexsurv models, but I don't have the patient level data to fit a model on, but only the point estimate. In other words I know how to get the survival probabilities across time from the mean OS/PFS, but how can I include that in the psm running through the hesim functions?

dincerti commented 3 years ago

Hi Andreas, below is an example in which you manually enter the parameters of the exponential survival models given information on median PFS/OS. You can add costs and utility information as needed. (Note that this is a really simple case where there are no covariates and no parameter uncertainty.

# (1) Setup decision problem
hesim_dat <- hesim_data(
  patients = data.frame(patient_id = 1),
  strategies = data.frame(strategy_id = 1:2)
)

# (2) Parameterize PFS/OS survival models

## Mean PFS/OS from literature
median_pfs <- 4
median_os <- 7

## Parameters for an exponential survival model
### We first create matrices containing the covariates that predict each
### parameter. For an exponential model there is only one parameter, the rate.
### The rate parameter is given by rate = exp(xb) where x is the covariate vector and 
### be is the vector of coefficients. Since there are no covariates, 
### we have an intercept only model with just 1 column. If there were parameter
### uncertainty, then each row in the matrix would be a random sample of the
### parameters for the PSA (we have none here, so the matrices only have one row)
rate_pfs <- log(2)/median_pfs
rate_os <- log(2)/median_os
coef_rate_pfs <- list(rate = matrix(log(rate_pfs)))
coef_rate_os <- list(rate = matrix(log(rate_os)))
colnames(coef_rate_pfs$rate) <- colnames(coef_rate_os$rate) <- "intercept"

### Now we specify that rate parameters correspond to an exponential survival model
params_exp <- params_surv_list(
  # PFS
  pfs = params_surv(
    coefs = coef_rate_pfs,
    dist = "exp"
  ),

  # OS
  os = params_surv(
    coefs = coef_rate_os,
    dist = "exp"
  )
)

# (3) Model simulation
## A full model consists of input data and the parameters
### The input data in this case is just the ID variables and a column of
### 1's since there are no covariates in the survival models
survmods_data <- expand(hesim_dat, by = c("patients", "strategies"))
survmods_data$intercept <- 1

### We now create the survival models
survmods <- create_PsmCurves(params_exp, input_data = survmods_data)

## We could then combine with costs and utility into a full PSM
## (we omit the costs and utility models here)
psm <- Psm$new(survival_models = survmods)

# We can now simulate outcomes 
## Let's simulate survival curves
psm$sim_survival(t = 0:10)

Note that median survival is consistent with what we had above, 4 for PFS and 7 for OS

head(psm$survival_[curve == 1])
   sample strategy_id patient_id grp_id curve t  survival
1:      1           1          1      1     1 0 1.0000000
2:      1           1          1      1     1 1 0.8408964
3:      1           1          1      1     1 2 0.7071068
4:      1           1          1      1     1 3 0.5946036
5:      1           1          1      1     1 4 0.5000000
6:      1           1          1      1     1 5 0.4204482
psm$survival_[curve == 2][1:8]
   sample strategy_id patient_id grp_id curve t  survival
1:      1           1          1      1     2 0 1.0000000
2:      1           1          1      1     2 1 0.9057237
3:      1           1          1      1     2 2 0.8203354
4:      1           1          1      1     2 3 0.7429971
5:      1           1          1      1     2 4 0.6729501
6:      1           1          1      1     2 5 0.6095068
7:      1           1          1      1     2 6 0.5520448
8:      1           1          1      1     2 7 0.5000000
heor-andreas commented 3 years ago

Thank you so much for this, Devin.

This was so useful and helped me understand the workings of the package more. I've also managed to work out how to use different means/medians for different strategies.

Thanks again!

dincerti commented 3 years ago

Thats great, Andreas! Really glad it was helpful. I'm going to close this issue for now, but don't hesitate to reach out again or submit new issues.