-
Notifications
You must be signed in to change notification settings - Fork 0
/
Medicare_Ineligibles.Rmd
1328 lines (1120 loc) · 58.3 KB
/
Medicare_Ineligibles.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "Impact of providing ART to Medicare ineligibles"
author: "Richard T. Gray"
date: Latest version - `r format(Sys.Date(), format="%B %d %Y")` <!---Add date automatically using R whenever markdown is run! --->
output:
word_document:
pandoc_args: --output="docs/Medicare_Ineligibles.docx"
reference_docx: docs/mystyles.docx
csl: docs/plos.csl
bibliography: docs/medicare_ineligibles.bib
---
This document summarizes a simple analysis to calculate the impact of
providing anti-retroviral therapy (ART) to people living with HIV (PLHIV)
in Australia who are Medicare ineligible. This analysis uses data from the
Australian HIV Observational Database Temporary Residents Access Study
(ATRAS) [@petoumenos2013australian]. The R code for these calculations is
available in the associated Rmarkdown file. The aim of these calculations
is to estimate the number of new HIV infections that occur through
transmission from Medicare ineligible people to their sexual partners, the
cost of providing ART to the Medicare ineligible population, and the
potential future cost of providing treatment to partners of Medicare
ineligibles who become infected. <!--- This is version v2.0 of the
calculations and document. Previous versions are available in a
corresponding git repository --->
This document is written in dynamic format using R markdown v2 within R
studio 0.98.1056 (using R version 3.1.2). Plots are created using the
package ggplot2. Further details are available in the associated Rmarkdown
file, which also contains the R code to produce all the results when the
markdown is run. We have suppressed code blocks in the output document.
<!--- The document was currently produced using Rmarkdown v2 within Rstudio
using `r substr(R.Version()$version.string,1,15), knitr, pandoc, and Miktex
(for Latex) for producing the associated PDF or Word Document output. The
analysis uses the R packages ggplot2 (version 2.0), dplyr, tidyr,
gridExtra. To update the results the markdown file needs to be loaded in
Rstudio or run using the tools separately. --->
```{r initialization,echo = FALSE,messages = FALSE,include=FALSE}
# Clear workspace
rm(list=ls())
options(scipen=999) # To get rid of scientific notation
# Source some useful functions
source(file.path("code", "FormatData.R"), echo = TRUE)
source(file.path("code", "LoadLibrary.R"), echo = TRUE)
source(file.path("code", "TidyLongitudinal.R"), echo = TRUE)
# Load libraries use in the analysis.
LoadLibrary(ggplot2)
LoadLibrary(dplyr)
LoadLibrary(tidyr)
LoadLibrary(gridExtra)
LoadLibrary(Hmisc)
LoadLibrary(knitr)
# Before we get started set some overarching variables so we can rerun
# results instead of generating new ones if necessary. Store outputs
# and initialize other script wide varuables.
outputFolder <- "output"
docFolder <- "docs"
currTime <- format(Sys.time(), "%y-%m-%d %H-%M-%S") # for appending to
# output files
# Specifications for loading previously generated results or saving results
# to file. The basic format of a file string
# is date and time + a file tag + " Inputs" or " Results".R. The defaults
# are set to FALSE and the user has to manually
# specifify the file to load. This is set up so long simulation runs do not
# need to be repeated to generate the dcoument.
loadFileTag <- ""
# "output/17-05-07 22-04-59 v2.2" Supplementary results short time between infection and diagnosis
# "output/17-05-08 14-34-51 v2.2" Resubmitted paper
# set to empty to run things a fresh. Manually enter file name tag to
# regenerate old results. loadFileTag has the structure of date and time +
# a file tag " Input.R" and " Results.R" are appended later.
loadVars <- FALSE # set to FALSE to run things a fresh.
loadResults <- FALSE # set to FALSE to run things a fresh. If TRUE a
# corresponding input file needs to exist and is
# loaded as well.
useSeed <- FALSE # use seed in loadVars file to get exactly the same
# results.
saveFileTag <- " v2.2" # tag for output file names to specify
# scenarios
saveVars <- TRUE # save input parameters so they can be loaded
# separately
saveResults <- TRUE # if TRUE saveVars is assumed TRUE as well.
# Check if output directories exist and create if necessary
if (!file.exists(outputFolder)){dir.create(file.path("./", outputFolder))}
if (!file.exists(docFolder)){dir.create(file.path("./", docFolder))}
# Produce plots in windows for viewing separately and save plots separately.
showPlots <- FALSE # show plots in separate windows
savePlots <- TRUE # save plots to file
knitplots <- TRUE # insert plots in the produced Rmarkdown document
saveFormat <- ".png" # Format for saving plots
```
### Methodology
This section summarizes the methodology used for the calculations. A
simple mathematical model is used to calculate the change in population
size over time and the number of new infections in partners of Medicare
ineligible people. Descriptions of model details, assumptions and input
parameters follow below.
```{r SimVariables,echo=FALSE}
if (!loadVars || !loadResults){
# If not loading from previously created file specifiy inputs
# Initialize parameters for running calculations
startyear <- 2011 # year ATRAS started represents year zero
datayears <- 3 # number of years we have data - year zero and 2
# years
# of followup
runyears <- 6 # number of years to run the model. Short term 5 to
# 10
numsims <- 1000 # number of sampled parameter sets to run
stochastic <- TRUE # run stochastic equations?
stochasticSims <- 20 # number of sims for each parameter set if
# stochastic calculations are set-up
# Generate and store a random integer for set.seed so we can rerun
# things exactly if we want to
currseed <- sample(1:10^6, 1)
set.seed(currseed)
} else {
# Save current values of some params as they will be replaced
oldloadFileTag <- loadFileTag
oldloadVars <- loadVars
oldloadResults <- loadResults
olduseSeed <- useSeed
oldsaveFileTag <- saveFileTag
oldsaveVars <- saveVars
oldsaveResults <- saveResults
oldshowPlots <- showPlots
oldsavePlots <- savePlots
oldknitplots <- knitplots
# Load the file with the saved input parameters
load(paste(loadFileTag, " Inputs.R", sep=""))
# Overwite the input file script variables with their current values.
loadFileTag <- oldloadFileTag
loadVars <- oldloadVars
loadResults <- oldloadResults
useSeed <- olduseSeed
saveFileTag <- oldsaveFileTag
saveVars <- oldsaveVars
saveResults <- oldsaveResults
showPlots <- oldshowPlots
savePlots <- oldsavePlots
knitplots <- oldknitplots
}
```
#### Demographics
For this analysis, we consider a population of PLHIV who are Medicare
ineligible with the characteristics of people in ATRAS
[@petoumenos2013australian]. The overall population is split into males
who are men who have sex with men (MSM) (which, for the purposes of this
analysis, we assume are exclusively homosexual) and all those who are not
MSM. The proportion of people in each of these populations is based on
ATRAS data and assumed constant. We used this compartmentalization of the
population to distinguish the risk of HIV infection rather than treatment
coverage and adherence.
The number of Medicare ineligibles can change over time with people
becoming eligible for Medicare provided ART and new temporary residents
entering the population. We represent this movement using a constant
growth rate for the population $\pi$ (which is positive for a growing
population
and negative for a declining population). <!--- In ATRAS approximately
20% of people become medicare eligible and leave the population each
year, this
would be lower bound on the rate of population change ---> Letting $N(y)$
equal the total population size in year $y$, the number of medicare
ineligible people in the population is then given by
$$N(y) = N(0)\pi^y.$$ For this analysis, we assume only a small change in
the population over time so the overall population size is relatively
constant.
#### Clinical characteristics
The main aim of this analysis is to investigate the effect of providing
all Medicare ineligible people in ATRAS with ART on HIV transmission. For
the calculations, we simply consider the proportion of the population
taking ART and the proportion of those on ART with viral suppression. Both
of these inputs can change over time based on the ATRAS data. We do not
consider different proportions for each population group. We used the most
recent data value for projections beyond the years of available data.
#### HIV transmission to partners
HIV transmission occurs through sexual intercourse between Medicare
ineligibles and their sexual partners. We assume all partners are Medicare
eligible and initiating ART does not change the risk of transmission to
partners (through changes in behavior for example). We also do not
consider onward transmission from newly infected partners. As the sexual
behavior for the ART and non-ART population is the same, we use a simple
risk equation approach with the overall annual risk of transmission
calculated from national data rather than incorporating complex sexual
behavior.
```{r betafunction, echo = FALSE, messages = FALSE}
# Define a function to calculate beta given an incidcence estimate, PLHIV,
# proportion on ART, and proportion with viral suppression.
beta <- function(incidence,numInfected,propart,propvs,effart){
return(incidence / ((1 - propart * propvs * effart) * numInfected))
}
```
Key assumptions:
* HIV transmission from Medicare ineligibles not on ART is the same as for
the Australian population of PLHIV not on ART.
* We assume partners of HIV positive people who are ineligible for Medicare
are Medicare eligible.
* Those with unsuppressed virus have the same transmission risk as those
not taking ART.
* Transmission parameters are constant over time.
#### Costs associated with ART provision
Our analysis includes an estimate of the annual cost of providing ART to
Medicare ineligibles and their partners who become infected. We obtained
estimates of the costs of providing treatment using previous work for
Australian settings [@schneider2014cost]. For sexual partners of Medicare
ineligibles who become infected with HIV we estimate the 'lifetime' cost
of providing and treatment.
#### Parameter table
Table 1 lists all input parameters and their values and ranges.
```{r inputParameters,echo=FALSE}
# If not loading from previously created file specifiy inputs
if (!loadVars && !loadResults){
# R code to define parameters for simulations. These are defined as
# uniform ranges [minimum, maximum]
# Next version may read this is from an external file. Samples are
# randomly obtained from these ranges and put into
# matrices to aid vectorised calculations
# Demographics --------------------------------------------------------
popsize <- c(400, 500);
pop_growth <- c(0.98, 1.02); # overall relative change in population
# size
prop_m <- c(0.4, 0.6); # proportion MSM - proportion non-MSM is
# calculated internally so that the
# proportions add up to 1.
# Clinical parameters --------------------------------------------------
# As these values can change of time we use hardcoded data values from
# ATRAS to track their change over time.
# Uncertainty or variation in these values is assumed to be the same
# over time and have the same relative factor.
prop_art_base <- c(0.63, 0.95,0.95) # hard coded
# National c(0.66, 0.66, 0.66)
prop_vs_base <- c(0.7,0.88,0.96) # hard coded
# National c(0.93,0.93,0.93)
prop_art_factor <- c(0.95, 1.05) # uncertainty in proportion not on ART
# so we don't get a proportion greater
# than 1
prop_vs_factor <- c(0.95, 1.05) # uncertainty in proportion not on ART
# so we don't get a proportion greater
# than 1
# HIV transmission parameters ------------------------------------------
# Assumed to remain constant over time
# First off we calculate a beta transmission value using inputs from the
# overall Australian population. Estimates are from James's
# back projection paper and David's treatment cascade calculations
numPLHIV <- 26640 # James's backprojection paper
numInfects <- 912 # James's backprojection paper
propMSM <- 0.75 # ASR
propMSMart <- 0.78 # Gay periodic surveys across Australia
propMSMvs <- 0.9 # Gay periodic surveys across Australia
propOtherart <- 0.55 # David's HIV cascade calculations based on
# prospection data
propOthervs <- 0.9 # assumed same for Gay periodics in line with
# AHOD
# data
effart <- 0.95 # efficay of ART for calculations (midway between
# epsilon_art we use for other calculations)
betan <- beta(numInfects * (1 - propMSM), numPLHIV * (1 - propMSM),
propOtherart, propOthervs, effart)
betanRange <- c(0.75 * betan, 1.25 * betan)
betam <- beta(numInfects * propMSM, numPLHIV * propMSM, propMSMart,
propMSMvs, effart)
betamRange <- c(0.75 * betam, 1.25 * betam)
# Reduction in HIV infectiouness due to viral suppression
epsilon_art <- c(0.9, 0.99)
# ART costs -----------------------------------------------------------
artcost <- c(10000, 20000) # for Medicare ineligibles. Assumed everyone
# is on first line ART + monitoring cost range
# c(7000, 15000) + c(3000, 5000)
# Calculation of lifetime cost of providing ART to those who become
# infected
# Average time of spending in each ART class assuming ~40 years of
# treatment from James's paper (median results rounded up)
yearsFirst <- 9
yearsSecond <- 14
yearsThird <- 3
totalLifeYears <- 40
yearsFourth <- totalLifeYears - (yearsFirst + yearsSecond + yearsThird)
# assume 40 years of ART use until death as the median age of ATRAS
# cohort is ~35
# From Karen's Prep paper. Cost is Australian dollars
costFirst <- 10685
costSecond <- 19364
costThird <- 31411
costFourth <- 28162
costUncertainty <- 0.25
monitoringCostLower <- 3000
monitoringCostUpper <- 5000
# Total cost for lifetime of treatment no discounting
lifecostYearly <- rep(costFourth, totalLifeYears)
lifecostYearly[1:yearsFirst] <- costFirst
lifecostYearly[(yearsFirst + 1):(yearsFirst + yearsSecond)] <-
costSecond
lifecostYearly[(yearsFirst + yearsSecond + 1):(yearsFirst + yearsSecond
+ yearsThird)] <- costThird
# Undiscounted lifetime cost of ART uncertainty
lifecost <- sum(lifecostYearly)
lifecostRange <- c((1 - costUncertainty) * lifecost,
(1 + costUncertainty) * lifecost)
lifecostRange <- lifecostRange + totalLifeYears * c(monitoringCostLower,
monitoringCostUpper)
# Discounting rate
discRate <- 0.05 # discounting rate
timeTreat <- c(4, 5) # time between infection and treatment where
# discounting would occur
# Supplementary results use c(2, 4)
# Weighted total cost for lifetime treatment with discounting. More
# complicated equation as it depends on the year so is defined below
# Save all the internal variables and parameter values
if (saveVars || saveResults){
save(list = ls(all = TRUE),
file = paste(outputFolder, "/", currTime, saveFileTag,
" Inputs.R", sep =""))
}
}
```
**Table 1** - Calculation input parameter ranges. Endnotes provide
justifications for these parameter ranges. The simulations used for the
calculations take samples from these ranges assuming a uniform
distribution.
Parameter | Description | Range | Reference
--------------------|----------------------------|----------------------------------------------|------------------------
**Demographic parameters** | | |
$N(0)$ | Overall population size in initial year | [`r popsize[1]` - `r popsize[2]`] | 1
$\pi$ | Multiplicative change in annual population | [`r pop_growth[1]` - `r pop_growth[2]`]/yr | 1
$p_m$ | Proportion of Medicare-ineligible population of PLHIV who are MSM | [`r prop_m[1]` - `r prop_m[2]`] | 1
$p_n$ | Proportion of Medicare-ineligible population of PLHIV who are non-MSM | Given by $1-p_m$ | 1
**Clinical parameters** | | |
$\theta$ | Proportion of population taking ART | 63% at enrollment and 95% after 12 months $\pm$ 5% | 2
$\psi$ | Proportion of population taking ART with undetectable viral load | 70% at enrollment, 88% after 12 months, and 96% after 24 months $\pm$ 5% | 2
**HIV transmission parameters** | | |
$\beta_n$ | Annual probability an untreated non-MSM transmits HIV to another person | [`r round(betanRange[1],4)` - `r round(betanRange[2],4)`] | 3
$\beta_m$ | Annual probability an untreated MSM transmits HIV to another person | [`r round(betamRange[1],4)` - `r round(betamRange[2],4)`] | 3
$\epsilon_{ART}$ | Efficacy of ART in preventing HIV transmission if virus is suppressed | [`r epsilon_art[1]` - `r epsilon_art[2]`] | 4
**Treatment costs** | | |
$c_{ART}$ | Average annual undiscounted cost of providing care and ART to Medicare ineligibles (including monitoring costs) | [`r FormatData(artcost[1], places = 0, money = TRUE)` - `r FormatData(artcost[2], places = 0, money = TRUE)`] | 5
$c_{life}$ | Average undiscounted lifetime cost of providing care and ART post infection (including monitoring costs)| [`r FormatData(lifecostRange[1], money = TRUE)` - `r FormatData(lifecostRange[2], money = TRUE)`] | 6
$r_{disc}$ | Discounting rate | `r 100*discRate`% | 7
$t_{ART}$ | Average time between infection and initiating ART | [`r timeTreat[1]` - `r timeTreat[2]`] years | 7
1. The 2013 ATRAS report <!--- data for 2011-12 when ATRAS started. Up to
460 in 2014 --->estimates there are 450 Medicare ineligible PLHIV in
Australia [@petoumenos2013australian]. We assume a range in the population
between 400 and 500 PLHIV with the potential for only a small change in
population size over time. In the population of 180 at enrollment, 89
(50%) of the males attributed their HIV infection to MSM exposure
[@petoumenos2013australian]. Assuming this reflects the demographic
distribution over time, we assume 40-60% of the population is MSM with the
remainder non-MSM.
2. At enrollment, 62.8% of ATRAS patients were already receiving ART with
71.8% having undetectable viral load [@petoumenos2013australian]. After
enrollment, all patients were put onto ART resulting in 87% having
undetectable viral load at 12 months and 96% having undetectable viral
load at 24 months [@petoumenos2013australian]. Based on the ATRAS data we
assume the percentage of Medicare ineligibles on ART increases from 70% to
95% with a range of $\pm$ 5% with the proportion with undetectable virus
increasing from 70% to 96% over two years with a range of $\pm$ 5%.
3. These values are calculated using data for the overall population of
PLHIV in Australia. Using the equation $I = N(1-\theta)\beta + N\theta(1-\psi)\beta + N\theta\psi(1-\epsilon_{ART})\beta = N\beta(1-\theta\psi\epsilon_{ART})$ where $I$ is the overall incidence in
Australian MSM and non-MSM, $N$ is the overall number of PLHIV in
Australia who are MSM and non-MSM, and the remaining parameters have the
same meaning
as in Table 1 we can estimate the value of $\beta$ for MSM and non-MSM.
In 2013, there were an estimated 26,640 PLHIV in Australia and 912 new
infections [@jansson2015inferring] of which around 75% are attributed to
homosexual contact [@kirby2014hivsupplement]. According to recent
estimates for the HIV treatment cascade in Australia, around 75% of MSM
living with HIV [@kirby2014hivsupplement] and 55% of non-MSM living with
HIV are taking ART [@kirby2014hivsupplement], respectively. In both MSM
and non-MSM taking ART, around 90% have an undetectable viral load
[@kirby2014hivsupplement; @petoumenos2013australian]. Putting these values
into the equation above and assuming $\pm$ 25% uncertainty produces the
values of $\beta_n$ and $\beta_m$.
4. We assume those with viral suppression have a 90-99% reduction in
transmission to their sexual partners. This assumption is in line with the
results from the HPTN-052 trial for those with detectable drug
[@cohen2011prevention] and the recent PARTNER study which recorded zero HIV
transmissions from 1166 HIV+ people to their sexual partners (though the
upper 95% confidence interval was 0.84, 0.88, and 0.97 per 100 couple-years
for MSM, heterosexual males, and heterosexual females respectively)
[@rodger2016sexual].
5. At enrollment, 83% of the ATRAS cohort on ART are taking
Tenofovir/Emtrcitabine (Truvada) as the 'backbone' of their regime. This
means the vast majority of those on treatment are taking first-line drugs.
For this analysis, we assume all patients are on and remain on first-line
ART over the period of analysis and undertake annual monitoring of their
infection. From Schneider et al., the average annual cost of first-line
drugs in Australia is \$10,685 (\$6,945- \$14,424) [@schneider2014cost].
Estimated annual medical costs for people living with HIV were also
estimated in Schneider et al. by CD4 count. Annual medical care and
infection monitoring for HIV+ people with CD4 $\ge$ 500 cells/$\mu$L,
CD4 350-499 cells/$\mu$L, CD4 $\ge$ 200-349 cells/$\mu$L, and CD4 < 200
cells/$\mu$L was estimated to equal A\$3,097, \$4,402, \$4,762, and
\$7,883, respectively. In recent years, patients in the AHOD cohort have
initiated ART at around 350 cells per $\mu$L [@petoumenos2013australian].
We therefore assume all patients have a CD4 count $\ge$ 200 cells/$\mu$L
and the associated annual monitoring costs to range from \$3,000 to $5,000.
Using these values, we assume a range in the annual
ART cost (including monitoring) of \$`r FormatData(artcost[1], places = 0)`
to \$`r FormatData(artcost[2], places = 0)`.
6. If a partner of a Medicare ineligible becomes infected with HIV then
they will eventually require care and treatment while they are living in
Australia. As we are not tracking their infection progression in this
analysis, we use an estimate for the lifetime cost of providing ART. An
analysis of the life expectancy of PLHIV in Australia given currently
available antiretroviral treatments suggests someone starting treatment in
their twenties will be taking ART for around 40 years
[@jansson2013currently] spending ~`r yearsFirst` years on first-line
drugs, ~`r yearsSecond` years on second-line drugs, ~`r yearsThird` years
on third-line drugs, and the reminder of the time on higher classes of
drug. Using the cost estimates from [@schneider2014cost], we assume the
annual costs of proving each line of drugs is
\$`r FormatData(costFirst, places = 0)`
for first-line drugs,
\$`r FormatData(costSecond, places = 0)`
for second-line drugs,
\$`r FormatData(costThird, places = 0)`
for third-line drugs, and
\$`r FormatData(costFourth, places = 0)`
for fourth and higher lines of drugs. Multiplying the values for each drug
class and summing produces the undiscounted treatment cost. To
account for all uncertainties in time on each treatment class and drug
costs we assume a range of $\pm$ 25% in the overall undiscounted cost.
Finally, we added the annual monitoring cost ranging from \$3,000 to $5,000
as described in footnote 4 to produce the undiscounted cost presented here.
7. To discount future costs of providing ART to people ineligible for
Medicare and those who become infected we apply a discount rate of 5% from
the year of enrollment in ATRAS for all treatment costs. For discounting
purposes, we include the time between infection and initiating ART, we
estimated this from data on the CD4 count at initiating therapy and
estimates for the rate of CD4 decline. In recent years, participants in the
AHOD cohort have initiated ART at around 350 cells per $\mu$L
[@petoumenos2013australian], it is estimated it takes 4.4 years for a
person to reach this CD4 count post infection [@jansson2015inferring]. We
therefore assume a range of 4 to 5 years for the time between infection
and ART initiation.
```{r vectoriseParams, echo = FALSE, messages = FALSE}
# Convert parameters to vectors and matrices for running in the
# calculations. Constants are stored as vectors and time varying
# parameters are stored as matrices. Each vector element or matrix row
# represents a specific sampling from the input parmater ranges.
if (useSeed){
set.seed(currseed)
} else {
set.seed(NULL)
}
# Demograhic parameters - Population size calulated by combining the
# initial population size and growth rate. As it is time varying
# population size is stored as a matrix
popsizemat <- matrix(0, numsims, runyears)
for (ii in 1:numsims){
popsizemat[ii, ] <- runif(1, popsize[1], popsize[2]) *
runif(1, pop_growth[1], pop_growth[2])^c(1:runyears)
}
prop_mvec <- runif(numsims, prop_m[1], prop_m[2])
prop_nvec <- 1-prop_mvec
# Clinical parameters (matrices). This is done by first converting
# proportions on ART and with viral suppression to vectors of
# equal length to number of simulation years and then inverting twice so
# the uncertianty factor does not produce a value great than 1.
# If the number of simulations years is greater than the number of data
# values the final data value is assumed to remain constant.
prop_art_baseVec <- rep(prop_art_base[length(prop_art_base)], runyears)
prop_vs_baseVec <- rep(prop_vs_base[length(prop_vs_base)] ,runyears)
# Replace start of vector with data values
prop_art_baseVec[1:length(prop_art_base)] <- prop_art_base
prop_vs_baseVec[1:length(prop_vs_base)] <- prop_vs_base
# Now create matrix of values by looping over number of simulations
prop_art_basemat <- matrix(0, numsims, runyears)
prop_vs_basemat <- matrix(0, numsims, runyears)
for (ii in 1:numsims) {
# Sample from multiplicative factor
tempFactor_art <- runif(1,prop_art_factor[1], prop_art_factor[2])
tempFactor_vs <- runif(1,prop_vs_factor[1], prop_vs_factor[2])
# Do double inversion and store in the row
prop_art_basemat[ii, ] <- 1-tempFactor_art * (1-prop_art_baseVec)
prop_vs_basemat[ii, ] <- 1-tempFactor_vs * (1-prop_vs_baseVec)
}
# Transmission parameters (vectors)
betanvec <- runif(numsims, betanRange[1], betanRange[2])
betamvec <- runif(numsims, betamRange[1], betamRange[2])
epsilon_artvec <- runif(numsims, epsilon_art[1], epsilon_art[2])
# Cost parameters
costartvec <- runif(numsims, artcost[1], artcost[2])
costlifevec <- runif(numsims, lifecostRange[1], lifecostRange[2])
costUncertainvec <- runif(numsims, 1 - costUncertainty,
1 + costUncertainty)
monitoringcostUncertainvec <- runif(numsims, monitoringCostLower,
monitoringCostUpper)
timeTreatVec <- runif(numsims, timeTreat[1], timeTreat[2])
```
#### Calculations for number of new infections caused by people ineligible for Medicare
We use simple risk-equation calculations to estimate the number of people
infected through partnerships with HIV-positive people ineligible for
Medicare. The appendix provides details of the calculations.
The total number of new infections equals the sum of infections caused by
Medicare-ineligible MSM and non-MSM each year. For each population, we
first calculate the probability of infecting another person using an
equation incorporating the level of ART use and viral suppression. The
proportion of the population on ART and with suppressed virus changes over
time, matching the ATRAS data in Table 1.
Using this probability, we estimate the number of new infections caused by
MSM and non-MSM Medicare-ineligibles each year through sampling from a
binomial distribution. <!--- In the Rmarkdown script there is an option to
use the risk equation approach instead of the sampling from a binomial
distribution. Given the relatively small population size and the high
levels of ART coverage and viral suppression, only a small number of new
infections are likely and we use the stochastic approach in this analysis.
---> Adding the population terms together gives the overall number of new
infections caused by Medicare-ineligibles in a given year and cumulatively
over time.
#### Cost calculations
The total cost of providing ART to people ineligible for Medicare
ineligibles is calculated by multiplying the annual number of people
ineligible for Medicare infected with HIV by the annual cost of providing
ART and summing over the period of analysis. For sexual partners of
Medicare-ineligibles who become infected with HIV we calculate the cost
per infection averted and overall future lifetime cost of providing care
and treatment to these people by multiplying the cumulative number of
people who acquire infection by the undiscounted (reported in Table 1)
lifetimecost and the discounted lifetime cost.
#### Simulations
To perform this analysis, we generated `r numsims` input parameter sets by
sampling from each of the parameter ranges in Table 1. For each of these
parameter sets we then ran `r stochasticSims` simulations to account for
stochastic variations. We ran each simulation for `r runyears-1` years
since the enrollment of patients into ATRAS. We then calculated summary
statistics using the results from each simulation.
```{r functions,echo = FALSE, messages = FALSE}
# Define two functions to calculate the incidence for a population. The
# second function can either be stocastic or deterministic
infect_prob <- function(propart, propvs, effart, beta){
return((1 - propart * propvs * effart) * beta)
}
popinfects <- function(popsize, prob, stochastic = FALSE){
if (!stochastic){
return(popsize * prob)
} else {
return(rbinom(length(prob), round(popsize), prob))
}
}
discountcosts <-function(yearlyCosts, discRate, startYear, delay){
# This function calculates the discounted lifetime costs for someone who
# becomes infected given
# a vector of estimated annual costs for treatment over time
# (yearlsCosts), the discount rate, the year
# since the start simulation when someone becomes infected (to account
# for discounting before they become infected),
# and any delay from infection to starting treatment (to account for
# discounting before they start treatment).
# The function returns the sum of the discounted annual costs
discountVec <- 1 / (1 + discRate)^(c(0:(length(yearlyCosts) - 1)) +
startYear + delay) # no discounting for year zero
yearlyDiscountCosts <- yearlyCosts * discountVec
return(sum(yearlyDiscountCosts))
}
```
```{r calculations, echo=FALSE, messages = FALSE, include = FALSE}
if (!loadResults){
# We are now ready to run the code that actually does the calculations
# for each simulation. This involves looping through each parameter
# set and calculating the incidence for each population using the
# current data and the counterfactual levels. <- Using the sampled and
# best fitting estimates and just the median of all values?? -->
# Determine how many runs to do for each parameter set
if (stochastic){
numruns <- stochasticSims
} else {
numruns <- 1
}
# Initialize output arrays
paramSet <- vector()
# For ATRAS simulations
infectsm <- matrix(0, numsims * numruns, runyears)
infectsn <- matrix(0, numsims * numruns, runyears)
costAtras <- matrix(0, numsims * numruns, runyears)
discountAtras <- matrix(0, numsims * numruns, runyears)
# For baseline simulations
infectsmBase <- matrix(0, numsims * numruns, runyears)
infectsnBase <- matrix(0, numsims * numruns, runyears)
# Discount rate vector - no discounting for year zero
discountVec <- 1 / (1 + discRate)^c(0:(runyears - 1))
# Do the calculations
for (ii in 1:numsims){
for (jj in 1:numruns){
# Row index for storage in output matrices
vecIndex <- (ii - 1) * numruns + jj
# Store parameter set index
paramSet <- c(paramSet, ii * matrix(1, runyears, 1))
# Infections casued by MSM - ATRAS
infectsm[vecIndex, ] <- popinfects(popsizemat[ii, ] *
prop_mvec[ii], infect_prob(prop_art_basemat[ii, ],
prop_vs_basemat[ii, ], epsilon_artvec[ii], betamvec[ii]),
stochastic)
# Infections casued by MSM - Baseline
infectsmBase[vecIndex, ] <- popinfects(popsizemat[ii, ] *
prop_mvec[ii], rep(infect_prob(prop_art_basemat[ii, 1],
prop_vs_basemat[ii, 1], epsilon_artvec[ii], betamvec[ii]),
runyears), stochastic)
# Infections caused by non-MSM - ATRAS
infectsn[vecIndex, ] <-
popinfects(popsizemat[ii, ] * (1 - prop_mvec[ii]),
infect_prob(prop_art_basemat[ii, ], prop_vs_basemat[ii, ],
epsilon_artvec[ii], betanvec[ii]), stochastic)
# Infections caused by non-MSM - Baseline
infectsnBase[vecIndex, ] <- popinfects(popsizemat[ii, ] *
(1 - prop_mvec[ii]), rep(infect_prob(prop_art_basemat[ii, 1],
prop_vs_basemat[ii, 1], epsilon_artvec[ii], betanvec[ii]),
runyears), stochastic)
# Cost of providing ART - undiscounted
costAtras[vecIndex, ] <- popsizemat[ii, ] * costartvec[ii]
# Cost of providing ART - discounted
discountAtras[vecIndex, ] <- popsizemat[ii, ] * costartvec[ii] *
discountVec
}
}
# Transpose to align with rows of the output matrices
paramSet <- t(paramSet)
# Reshape the simulation output into a dataframe so it is easier for
# analysis and plotting.
msmInfects <- TidyLongitudinal(infectsm, 1, firstCol = "simulation") %>%
rename(infectsbymsm = value)
nonmsmInfects <- TidyLongitudinal(infectsn, 1,
firstCol = "simulation") %>%
rename(infectsbynonmsm = value)
msmInfectsBase <- TidyLongitudinal(infectsmBase, 1,
firstCol = "simulation") %>%
rename(infectsbymsmbase = value)
nonmsmInfectsBase <- TidyLongitudinal(infectsnBase, 1,
firstCol = "simulation") %>%
rename(infectsbynonmsmbase = value)
costAtrasVec <- TidyLongitudinal(costAtras, 1,
firstCol = "simulation") %>%
rename(costatras = value)
discountAtrasVec <- TidyLongitudinal(discountAtras, 1,
firstCol = "simulation") %>%
rename(costatrasdisc = value)
# Merge the results we want into one data frame, order simulations and
# append parameterset number. Each observation represents a
# single calculation of incidence
newinfections <- msmInfects %>%
inner_join(nonmsmInfects,
by = c("simulation", "year")) %>%
mutate(totalinfects = infectsbymsm + infectsbynonmsm) %>%
# Baseline results
inner_join(msmInfectsBase, by = c("simulation", "year")) %>%
inner_join(nonmsmInfectsBase, by = c("simulation", "year")) %>%
mutate(totalinfectsbase = infectsbymsmbase + infectsbynonmsmbase) %>%
# Averted infections
mutate(infectsaverted = totalinfectsbase - totalinfects) %>%
# Costs
inner_join(costAtrasVec, by = c("simulation", "year")) %>%
inner_join(discountAtrasVec, by = c("simulation", "year")) %>%
mutate(lifecostatras = totalinfects * costlifevec,
lifecostbase = totalinfectsbase * costlifevec,
lifecostsaving = (totalinfectsbase - totalinfects) *
costlifevec)
# Order by simulation number
newinfections <- newinfections[order(newinfections$simulation), ]
# Add parameterset number and reorder to put in first column
newinfections$paramset <- as.numeric(paramSet)
newinfections <- select(newinfections, paramset, everything())
# Subtract a year from year column to start things at year zero
newinfections$year <- newinfections$year - 1
# Discounted costs - Need to loop through each line of newinfections to
# account for the different startyears
totalLifeYears * c(monitoringCostLower, monitoringCostUpper)
simCostsDisc <- rep(0, nrow(newinfections))
for (ii in 1:nrow(newinfections)){
simCostsDisc[ii] <-sum(discountcosts(lifecostYearly *
costUncertainvec[newinfections$paramset[ii]] +
monitoringcostUncertainvec[newinfections$paramset[ii]],
discRate,
newinfections$year[ii], timeTreatVec[newinfections$paramset[ii]]))
}
newinfections <- newinfections %>%
mutate(lifecostatrasdisc = totalinfects * simCostsDisc,
lifecostbasedisc = totalinfectsbase * simCostsDisc,
lifecostsavingdisc = simCostsDisc * (totalinfectsbase -
totalinfects))
# Summed costs
newinfections <- newinfections %>%
mutate(sumatrascost = costatras + lifecostatras,
sumatrascostdisc = costatrasdisc + lifecostatrasdisc)
# Write results to file
# Save all the internal variables and parameter values
if (saveResults){
save(newinfections, file = paste(outputFolder, "/", currTime,
saveFileTag, " Results.R", sep = ""))
write.csv(newinfections, file = paste(outputFolder, "/", currTime,
saveFileTag, " Results.csv", sep = ""))
}
} else {
# Load previously generated results
load(paste(loadFileTag, " Results.R", sep= ""))
}
```
### Results
<!--- This section contains code converting the calculation results into figures and summary statistics. Results are then written up using
the calculated values-->
```{r analysis, echo=FALSE,messages = FALSE,include=FALSE}
# Do some data manipulation for producing the cumulative number of
# infections and infections averted.
infectsSum <- newinfections %>%
select(year, simulation, totalinfectsbase, totalinfects) %>%
group_by(simulation) %>%
summarise(newinfectionsbase = sum(totalinfectsbase),
newinfections = sum(totalinfects)) %>%
select(simulation, everything())
avertedSum <- newinfections %>%
select(year, simulation, infectsaverted) %>%
group_by(simulation) %>%
summarise(totalaverted = sum(infectsaverted)) %>%
select(simulation, everything())
costsSum <- newinfections %>%
select(year, simulation, costatras, costatrasdisc, lifecostbase,
lifecostatras, lifecostbasedisc, lifecostatrasdisc) %>%
gather("scenario", "totalcost", 3:8, factor_key = TRUE) %>%
group_by(scenario, simulation) %>%
summarise(totalcost = sum(totalcost)) %>%
select(simulation, everything()) %>%
spread(scenario, totalcost)
costsSum2 <- newinfections %>%
select(year, simulation, lifecostbase, sumatrascost, lifecostbasedisc,
sumatrascostdisc) %>%
gather("scenario", "totalcost", 3:6, factor_key = TRUE) %>%
group_by(scenario, simulation) %>%
summarise(totalcost = sum(totalcost)) %>%
select(simulation, everything())
costsSum3 <- newinfections %>%
select(year, simulation, costatras, lifecostsaving, costatrasdisc,
lifecostsavingdisc) %>%
gather("scenario", "totalcost", 3:6, factor_key = TRUE) %>%
group_by(scenario, simulation) %>%
summarise(totalcost = sum(totalcost)) %>%
select(simulation, everything())
# costsSum3 used for the final paper
# Basic summary calculations ---------------------------------------------
# Median number of infections at enrolment and after 5 years.
startinfects <- filter(newinfections, year == 0)$totalinfects
endinfects <- filter(newinfections, year == 5)$totalinfects
startinfectsbase <- filter(newinfections, year == 0)$totalinfectsbase
endinfectsbase <- filter(newinfections, year == 5)$totalinfectsbase
# Median infections averted
avertmed <- median(avertedSum$totalaverted)
avertiqr <- IQR(avertedSum$totalaverted)
# Costs
medacost <- median(costsSum$costatras)
iqracost <- IQR(costsSum$costatras)
medacostdisc <- median(costsSum$costatrasdisc)
iqracostdisc <- IQR(costsSum$costatrasdisc)
# Lifetime costs
medlbcost <- median(costsSum$lifecostbase)
iqrlbcost <- IQR(costsSum$lifecostbase)
medlacost <- median(costsSum$lifecostatras)
iqrlacost <- IQR(costsSum$lifecostatras)
medlbcostdisc <- median(costsSum$lifecostbasedisc)
iqrlbcostdisc <- IQR(costsSum$lifecostbasedisc)
medlacostdisc<- median(costsSum$lifecostatrasdisc)
iqrlacostdisc <- IQR(costsSum$lifecostatrasdisc)
# total costs
medtotcostbasedisc<- median(costsSum$lifecostbasedisc)
iqrtotcostbasedisc <- IQR(costsSum$lifecostbasedisc)
medtotcost <- median(costsSum$costatras + costsSum$lifecostatras)
iqrtotcost <- IQR(costsSum$costatras + costsSum$lifecostatras)
medtotcostdisc<- median(costsSum$costatrasdisc +
costsSum$lifecostatrasdisc)
iqrtotcostdisc <- IQR(costsSum$costatrasdisc +
costsSum$lifecostatrasdisc)
# Cost per infection averted
medcostpia <- median(costsSum$costatras / avertedSum$totalaverted)
iqrcostpia <- IQR(costsSum$costatras / avertedSum$totalaverted)
medcostpiadisc <- median(costsSum$costatrasdisc / avertedSum$totalaverted)
iqrcostpiadisc <- IQR(costsSum$costatrasdisc / avertedSum$totalaverted)
# Savings and net costs
medsaving <- median(costsSum$lifecostbase - costsSum$lifecostatras)
iqrsaving <- IQR(costsSum$lifecostbase - costsSum$lifecostatras)
medsavingdisc <- median(costsSum$lifecostbasedisc -
costsSum$lifecostatrasdisc)
iqrsavingdisc <- IQR(costsSum$lifecostbasedisc -
costsSum$lifecostatrasdisc)
mednetcost<- median(costsSum$costatras - costsSum$lifecostbase +
costsSum$lifecostatras)
iqrnetcost <- IQR(costsSum$costatras - costsSum$lifecostbase +
costsSum$lifecostatras)
mednetcostdisc <- median(costsSum$costatrasdisc -
costsSum$lifecostbasedisc +
costsSum$lifecostatrasdisc)
iqrnetcostdisc <- IQR(costsSum$costatrasdisc -
costsSum$lifecostbasedisc +
costsSum$lifecostatrasdisc)
```
During the first year after enrollment for ATRAS, the number of new
infections caused by Medicare ineligible people is estimated to be
`r median(startinfects)` (IQR: `r median(startinfects)-IQR(startinfects)/2` - `r median(startinfects)+IQR(startinfects)/2`).
As a percentage of the infected Medicare-ineligible population, this
number of new infections equates to
`r round(100*median(startinfects)/median(popsizemat[,1]),1)`% of the
population (Figure 1).
The impact of expanding ATRAS to all Medicare ineligibles and achieving
almost universal viral suppression is to reduce annual new infections to a
median of `r median(endinfects)` (IQR:
`r median(endinfects)-IQR(endinfects)/2` -
`r median(endinfects)+IQR(endinfects)/2`) after `r runyears-1` years
(Figure 1).
This corresponds to
`r round(100*median(endinfects)/median(popsizemat[,5]),)`% of the Medicare
ineligible population.
```{r plotcode, echo=FALSE,messages = FALSE,include=FALSE}
# Create plots of results
graphics.off()
# Initialize plotting properties
colourmap <- c("#999999","#000000", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7") # Colour blind palette with grey and black
# Theme for plot variables
opts <- theme_bw() + theme(text = element_text(face = "bold", size = 12,
colour = "black"),
axis.text.x = element_text(face = "plain", size = 10, colour = "black"),
axis.text.y = element_text(face = "plain", size = 10, colour = "black"),
axis.line = element_line(colour = "black"),
axis.ticks = element_line(colour = "black"),
legend.position = "top",
legend.background = element_rect(),
legend.key = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line.x = element_line(colour = "black"),
axis.line.y = element_line(colour = "black")
)
simsplot <- ggplot(data = newinfections,
aes(x = year, group = simulation)) +
geom_line(aes(y = totalinfectsbase,colour="Baseline simulations"),
size = 1.05) + # Baseline simulations
geom_line(aes(y = totalinfects,colour="ATRAS simulations"),
size = 1.05) + # ATRAS simulations
stat_summary(aes(y = totalinfectsbase, group = 1), fun.y = median,
geom = "line", colour = colourmap[2], size = 1.2) +
# Median of baseline simulations
stat_summary(aes(y = totalinfects, group = 1), fun.y = median,
geom = "line", colour = colourmap[7], size = 1.2) +