time-dependent-phase-type.R 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. # We will use cycles from 0 to 100
  2. cycles <- 0:100
  3. # Create an array for the state membership
  4. state_membership <- array(NA_real_, c(length(cycles), 5), list(cycle = cycles, state = c("Healthy", "DiseasedA", "DiseasedB", "DiseasedC", "Dead")))
  5. state_membership[1, ] <- c(1, 0, 0, 0, 0)
  6. # Define the survival model parameters
  7. # - Healthy to Diseased
  8. lambda_inc <- 2e-5
  9. gamma_inc <- 2.5
  10. # - Healthy to Dead
  11. a_general <- 0.2
  12. b_general <- 1e-7
  13. # - Diseased to Dead
  14. lambda_surv <- 0.2
  15. gamma_surv <- 0.5
  16. # Calculate the hazard rates for the transitions out of the Healthy state
  17. healthy_haz <- array(NA_real_, c(length(cycles), 2), list(cycle = cycles, to = c("Diseased", "Dead")))
  18. healthy_haz[, 1] <- lambda_inc * ((cycles + 1) ^ gamma_inc - cycles ^ gamma_inc)
  19. healthy_haz[, 2] <- b_general / a_general * (exp(a_general * (cycles + 1)) - exp(a_general * cycles))
  20. # Fit a phase-type distribution to the Weibull distribution for disease survival
  21. fit <- mapfit::phfit.density(
  22. ph = mapfit::cf1(3),
  23. f = function(x) lambda_surv * gamma_surv * x ^ (gamma_surv - 1) * exp(-lambda_surv * x ^ gamma_surv))
  24. Q <- Matrix::as.matrix(fit$model@Q)
  25. P <- expm::expm(Q)
  26. # Create an array for transition probabilities in each cycle
  27. transition_probs <- array(
  28. NA_real_,
  29. c(length(cycles), 10),
  30. list(
  31. cycle = cycles,
  32. transition = c("Healthy->DiseasedA", "Healthy->DiseasedB", "Healthy->DiseasedC", "Healthy->Dead", "DiseasedA->DiseasedA", "DiseasedA->DiseasedB", "DiseasedB->DiseasedB", "DiseasedA->DiseasedC", "DiseasedB->DiseasedC", "DiseasedC->DiseasedC")))
  33. # The transition probabilities for the Healthy state can be calculated already
  34. healthy_to_diseased <- healthy_haz[, 1] / rowSums(healthy_haz) * (1 - exp(-rowSums(healthy_haz)))
  35. transition_probs[, 1:3] <- sapply(1:3, function(i) healthy_to_diseased * fit$model@alpha[i])
  36. transition_probs[, 4] <- healthy_haz[, 2] / rowSums(healthy_haz) * (1 - exp(-rowSums(healthy_haz)))
  37. transition_probs[, 5:10] <- t(sapply(cycles, function(i) P[upper.tri(P, diag = TRUE)]))
  38. # Run the cohort simulation
  39. for (i in 2:length(cycles)) {
  40. TP <- matrix(0, 5, 5)
  41. TP[1, 5] <- transition_probs[i - 1, 4]
  42. TP[1, 2:4] <- transition_probs[i - 1, 1:3]
  43. TP[1, 1] <- 1 - sum(TP[1, 2:5])
  44. TP[(row(TP) %in% (2:4)) & (col(TP) %in% (2:4) & (row(TP) <= col(TP)))] <- transition_probs[i - 1, 5:10]
  45. TP[2:5, 5] <- 1 - rowSums(TP[2:5, 1:4])
  46. state_membership[i, ] <- t(TP) %*% state_membership[i - 1, ]
  47. }
  48. summarised_state_membership <- cbind(state_membership[, 1], rowSums(state_membership[, 2:4]), state_membership[, 5])
  49. dimnames(summarised_state_membership) <- list(cycle = cycles, state = c("Healthy", "Diseased", "Dead"))