From c547d6570322fcc54930cf67b2566c60c08ece0e Mon Sep 17 00:00:00 2001 From: Quarto GHA Workflow Runner Date: Mon, 18 Dec 2023 03:08:31 +0000 Subject: [PATCH] Built site for gh-pages --- .nojekyll | 2 +- authors.html | 16 +- chapter_07.html | 4 +- chapter_10.html | 22 +- chapter_11.html | 47 +- chapter_16.html | 490 ++++----- .../fig-predben_continuous_outcome-1.png | Bin 69140 -> 67590 bytes chapter_18.html | 974 +++++++++--------- index.html | 2 +- search.json | 14 +- 10 files changed, 788 insertions(+), 783 deletions(-) diff --git a/.nojekyll b/.nojekyll index 58da5cd..884e1f0 100644 --- a/.nojekyll +++ b/.nojekyll @@ -1 +1 @@ -29f3f078 \ No newline at end of file +143b16db \ No newline at end of file diff --git a/authors.html b/authors.html index 99f0a2d..1ea62c2 100644 --- a/authors.html +++ b/authors.html @@ -293,25 +293,33 @@

11  +Jessica L. Rohmann +Charité, Universitätsmedizin Berlin, Berlin, Germany + + Johanna Muñoz Julius Center for Health Sciences and Primary Care, University Medical Center Utrecht, Utrecht University, Utrecht, The Netherlands - + Katrine Strandberg-Larsen Department of Public Health, University of Copenhagen, Copenhagen, Denmark - + Konstantina Chalkou Institute of Social and Preventive Medicine (ISPM), University of Bern, Bern, Switzerland - + Mohammad Ehsanul Karim School of Population and Public Health, University of British Columbia, Vancouver, Canada - + Tammy Jiang Biogen, Cambridge, MA, United States + +Tat Thang Vo +The Wharton School, The University of Pennsylvania, Philadelphia, Pennsylvania, United States + diff --git a/chapter_07.html b/chapter_07.html index 749f867..73413e3 100644 --- a/chapter_07.html +++ b/chapter_07.html @@ -1862,8 +1862,8 @@

Version info

[52] lifecycle_1.0.4 chk_0.9.1 stringi_1.8.3 [55] yaml_2.3.8 carData_3.0-5 promises_1.2.1 [58] crayon_1.5.2 lattice_0.20-45 splines_4.2.3 -[61] pander_0.6.5 pillar_1.9.0 igraph_1.6.0 -[64] uuid_1.1-1 codetools_0.2-19 crul_1.4.0 +[61] pander_0.6.5 pillar_1.9.0 uuid_1.1-1 +[64] igraph_1.6.0 codetools_0.2-19 crul_1.4.0 [67] glue_1.6.2 evaluate_0.23 msm_1.7.1 [70] mitools_2.4 fontLiberation_0.1.0 data.table_1.14.10 [73] vctrs_0.6.5 httpuv_1.6.13 gtable_0.3.4 diff --git a/chapter_10.html b/chapter_10.html index facc4c0..c607ae5 100644 --- a/chapter_10.html +++ b/chapter_10.html @@ -860,16 +860,16 @@

REM vs. STD -0.9 (0.73; 1.09) +0.9 (0.73; 1.08) TOCI vs. STD @@ -893,7 +893,7 @@

REM vs. TOCI -1.02 (0.75; 1.26) +1.01 (0.75; 1.26) @@ -1342,12 +1342,12 @@

sucra.uc$ranking.random
 ADA160/80     FIL100     FIL200 GOL200/100      INF10       INF5    OZA0.92 
-0.27545455 0.19454545 0.40545455 0.63909091 0.60181818 0.75363636 0.77818182 
+0.28363636 0.16818182 0.44000000 0.61818182 0.61636364 0.75909091 0.74909091 
        PBO      TOF10      UPA45       UST6     VED300 
-0.01818182 0.39454545 0.98454545 0.34090909 0.61363636 
+0.01727273 0.42090909 0.97181818 0.35272727 0.60272727
-

These results indicate that 98.5% of the evaluated treatments are worse than UPA45.

+

These results indicate that 97.2% of the evaluated treatments are worse than UPA45.

diff --git a/chapter_11.html b/chapter_11.html index 381b082..249b1f9 100644 --- a/chapter_11.html +++ b/chapter_11.html @@ -755,29 +755,30 @@

Version info

[7] Formula_1.2-5 shiny_1.8.0 metafor_4.4-0 [10] yaml_2.3.8 numDeriv_2016.8-1.1 R2WinBUGS_2.1-22 [13] pillar_1.9.0 lattice_0.20-45 glue_1.6.2 -[16] digest_0.6.33 promises_1.2.1 rvest_1.0.3 -[19] minqa_1.2.6 colorspace_2.1-0 R2jags_0.7-1 -[22] mcmcplots_0.4.3 htmltools_0.5.7 httpuv_1.6.13 -[25] Matrix_1.6-4 pkgconfig_2.0.3 purrr_1.0.2 -[28] xtable_1.8-4 scales_1.3.0 webshot_0.5.5 -[31] svglite_2.1.3 rjags_4-15 later_1.3.2 -[34] metadat_1.2-0 lme4_1.1-35.1 tibble_3.2.1 -[37] farver_2.1.1 generics_0.1.3 ellipsis_0.3.2 -[40] withr_2.5.2 cli_3.6.2 magrittr_2.0.3 -[43] mime_0.12 evaluate_0.23 fansi_1.0.6 -[46] nlme_3.1-162 MASS_7.3-58.2 xml2_1.3.6 -[49] tools_4.2.3 lifecycle_1.0.4 stringr_1.5.1 -[52] munsell_0.5.0 compiler_4.2.3 systemfonts_1.0.5 -[55] rlang_1.1.2 nloptr_2.0.3 grid_4.2.3 -[58] rstudioapi_0.15.0 CompQuadForm_1.4.3 htmlwidgets_1.6.4 -[61] miniUI_0.1.1.1 labeling_0.4.3 rmarkdown_2.25 -[64] boot_1.3-28.1 gtable_0.3.4 codetools_0.2-19 -[67] abind_1.4-5 R6_2.5.1 gridExtra_2.3 -[70] knitr_1.45 denstrip_1.5.4 fastmap_1.1.1 -[73] utf8_1.2.4 mathjaxr_1.6-0 ggExtra_0.10.1 -[76] stringi_1.8.3 parallel_4.2.3 Rcpp_1.0.11 -[79] vctrs_0.6.5 tidyselect_1.2.0 xfun_0.41 -[82] coda_0.19-4 +[16] digest_0.6.33 RColorBrewer_1.1-3 promises_1.2.1 +[19] minqa_1.2.6 rvest_1.0.3 colorspace_2.1-0 +[22] R2jags_0.7-1 Matrix_1.6-4 mcmcplots_0.4.3 +[25] htmltools_0.5.7 httpuv_1.6.13 plyr_1.8.9 +[28] pkgconfig_2.0.3 purrr_1.0.2 xtable_1.8-4 +[31] scales_1.3.0 webshot_0.5.5 svglite_2.1.3 +[34] rjags_4-15 later_1.3.2 ggstats_0.5.1 +[37] metadat_1.2-0 lme4_1.1-35.1 tibble_3.2.1 +[40] farver_2.1.1 generics_0.1.3 ellipsis_0.3.2 +[43] withr_2.5.2 cli_3.6.2 magrittr_2.0.3 +[46] mime_0.12 evaluate_0.23 GGally_2.2.0 +[49] fansi_1.0.6 nlme_3.1-162 MASS_7.3-58.2 +[52] xml2_1.3.6 tools_4.2.3 lifecycle_1.0.4 +[55] stringr_1.5.1 munsell_0.5.0 compiler_4.2.3 +[58] systemfonts_1.0.5 rlang_1.1.2 nloptr_2.0.3 +[61] grid_4.2.3 rstudioapi_0.15.0 CompQuadForm_1.4.3 +[64] htmlwidgets_1.6.4 miniUI_0.1.1.1 labeling_0.4.3 +[67] rmarkdown_2.25 boot_1.3-28.1 gtable_0.3.4 +[70] codetools_0.2-19 abind_1.4-5 R6_2.5.1 +[73] gridExtra_2.3 knitr_1.45 denstrip_1.5.4 +[76] fastmap_1.1.1 utf8_1.2.4 mathjaxr_1.6-0 +[79] ggExtra_0.10.1 stringi_1.8.3 parallel_4.2.3 +[82] Rcpp_1.0.11 vctrs_0.6.5 tidyselect_1.2.0 +[85] xfun_0.41 coda_0.19-4
diff --git a/chapter_16.html b/chapter_16.html index 59b0282..8cc4235 100644 --- a/chapter_16.html +++ b/chapter_16.html @@ -293,13 +293,13 @@

head(ds)
-
  studyid treat         z1          z2  y
-1       1     0 -1.0250374  0.49359495 11
-2       1     0  1.3634580 -0.06700193 11
-3       1     1 -1.0207586 -0.41125330  8
-4       1     0  0.1811554  1.35029464 11
-5       1     0  0.7933182 -0.82219469 11
-6       1     1 -0.1877892  1.71953547 10
+
  studyid treat         z1         z2  y
+1       1     1 -1.0619070  0.5036365  9
+2       1     0  0.6982086 -0.8906105 11
+3       1     0 -1.3479618  1.3276495 11
+4       1     0 -0.7654394  1.2064922 11
+5       1     1 -0.8290456  0.5130794  8
+6       1     0 -0.4027927 -1.5423636 11

The simulated dataset contains information on the following variables:

@@ -326,9 +326,9 @@

0
-(N=305)
+(N=296)
1
-(N=295)
+(N=304) Overall
(N=600)
@@ -342,15 +342,15 @@

Mean (SD) -0.118 (1.06) -0.0136 (1.07) -0.0664 (1.07) +0.0145 (1.04) +0.0104 (1.07) +0.0124 (1.05) Median [Min, Max] -0.0748 [-2.75, 3.05] --0.0745 [-3.21, 2.67] --0.00441 [-3.21, 3.05] +0.0271 [-2.62, 2.69] +-0.00402 [-2.18, 3.15] +0.00818 [-2.62, 3.15] z2 @@ -360,15 +360,15 @@

Mean (SD) -0.0401 (1.05) --0.0362 (1.05) -0.00259 (1.05) +-0.0210 (1.01) +-0.0459 (1.00) +-0.0336 (1.01) Median [Min, Max] -0.0341 [-3.17, 2.52] --0.106 [-2.84, 2.93] --0.00570 [-3.17, 2.93] +-0.0340 [-2.90, 3.04] +-0.0599 [-2.91, 3.16] +-0.0448 [-2.91, 3.16] studyid @@ -378,38 +378,38 @@

1 -51 (16.7%) -49 (16.6%) +48 (16.2%) +52 (17.1%) 100 (16.7%) 2 -46 (15.1%) -54 (18.3%) +50 (16.9%) +50 (16.4%) 100 (16.7%) 3 -58 (19.0%) -42 (14.2%) +55 (18.6%) +45 (14.8%) 100 (16.7%) 4 -52 (17.0%) -48 (16.3%) +46 (15.5%) +54 (17.8%) 100 (16.7%) 5 -50 (16.4%) -50 (16.9%) +47 (15.9%) +53 (17.4%) 100 (16.7%) 6 -48 (15.7%) -52 (17.6%) +50 (16.9%) +50 (16.4%) 100 (16.7%) @@ -462,7 +462,7 @@

+<environment: 0x55f00313cef0>

We can fit the treatment effect model as follows:

@@ -485,36 +485,36 @@

+delta[2] -3.3771 -2.9628 -2.6712 -2.3931 -2.0242 +gamma[1] -0.5379 -0.5174 -0.4959 -0.4790 -0.4319 +gamma[2] 0.5242 0.5565 0.5765 0.5931 0.6172 +sd 0.7587 0.8959 1.0888 1.2883 1.6156 @@ -525,10 +525,10 @@

round(treatment.effect(ipd, samples, newpatient = c(z1 = 1, z2 = 0.5)), 2)
0.025   0.5 0.975 
--3.70 -3.00 -2.48 
+-3.50 -2.81 -2.17
-

This means that the predicted outcome for patient with covariate values z1 = 1 and z2 = 0.5 will differ by -3 units when receiving the active treatment (treat = 1) as compared to the control treatment (treat = 0).

+

This means that the predicted outcome for patient with covariate values z1 = 1 and z2 = 0.5 will differ by -2.81 units when receiving the active treatment (treat = 1) as compared to the control treatment (treat = 0).

We can also predict treatment benefit for all patients in the sample, and look at the distribution of predicted benefit.

library(dplyr)
@@ -590,7 +590,7 @@ 

round(treatment.effect(ipd, samples, newpatient = c(1,0.5)), 2)

0.025   0.5 0.975 
--3.94 -2.95 -1.79 
+-4.37 -2.87 -1.82
@@ -604,13 +604,13 @@

ds2 <- generate_ipdma_example(type = "binary")
 head(ds2)
-
  studyid treat         w1         w2 y
-1       1     1  0.3085440  0.1575700 1
-2       1     0  0.4926325 -0.4840050 0
-3       1     1  2.5380713 -0.6867120 0
-4       1     1  1.5699597  1.5699588 1
-5       1     0 -1.1898302  1.0758754 0
-6       1     0 -0.9250433 -0.2722173 1
+
  studyid treat          w1        w2 y
+1       1     0 -1.44373045 0.8321901 0
+2       1     1 -0.48748747 0.5844157 0
+3       1     1 -0.39070957 0.2867364 0
+4       1     0  1.38918716 1.0353666 1
+5       1     0 -0.29848976 3.0342741 0
+6       1     1 -0.03002357 2.0635757 1

The simulated dataset contains information on the following variables:

@@ -637,9 +637,9 @@

0
-(N=322)
+(N=307)
1
-(N=278)
+(N=293) Overall
(N=600)
@@ -653,15 +653,15 @@

Mean (SD) --0.0283 (0.965) -0.0915 (1.02) -0.0272 (0.994) +0.0271 (0.986) +-0.0340 (1.04) +-0.00274 (1.01) Median [Min, Max] --0.0475 [-2.69, 2.49] -0.123 [-2.71, 2.54] -0.0111 [-2.71, 2.54] +0.109 [-3.06, 3.14] +-0.0394 [-3.09, 2.79] +0.0257 [-3.09, 3.14] w2 @@ -671,15 +671,15 @@

Mean (SD) -0.0447 (0.985) -0.00111 (0.975) -0.0245 (0.980) +-0.0220 (1.01) +0.0431 (0.963) +0.00978 (0.986) Median [Min, Max] -0.0640 [-2.30, 3.02] -0.0276 [-3.04, 2.13] -0.0317 [-3.04, 3.02] +-0.0243 [-3.11, 3.26] +0.0686 [-2.65, 2.46] +0.0198 [-3.11, 3.26] studyid @@ -689,38 +689,38 @@

1 -54 (16.8%) -46 (16.5%) +49 (16.0%) +51 (17.4%) 100 (16.7%) 2 -57 (17.7%) -43 (15.5%) +60 (19.5%) +40 (13.7%) 100 (16.7%) 3 -54 (16.8%) -46 (16.5%) +49 (16.0%) +51 (17.4%) 100 (16.7%) 4 -49 (15.2%) -51 (18.3%) +47 (15.3%) +53 (18.1%) 100 (16.7%) 5 -51 (15.8%) -49 (17.6%) +48 (15.6%) +52 (17.7%) 100 (16.7%) 6 -57 (17.7%) -43 (15.5%) +54 (17.6%) +46 (15.7%) 100 (16.7%) @@ -778,7 +778,7 @@

+<environment: 0x55f006ccacf8>
@@ -797,37 +797,37 @@

+ 2.5% 25% 50% 75% 97.5% +alpha[1] -0.64744 -0.49202 -0.159281 0.03591 0.11782 +alpha[2] -0.47012 -0.33549 -0.183885 0.04210 0.12768 +alpha[3] -0.80523 -0.45864 -0.234532 -0.03354 0.50730 +alpha[4] -0.30353 -0.12156 0.043911 0.22654 0.38940 +alpha[5] -0.76405 -0.37814 -0.203506 -0.04570 0.36505 +alpha[6] -0.39156 -0.26771 -0.145874 0.05104 0.19871 +beta[1] -0.21175 -0.07668 0.006964 0.09062 0.17487 +beta[2] -0.18305 -0.03635 0.029703 0.09392 0.20854 +delta[1] 0.00000 0.00000 0.000000 0.00000 0.00000 +delta[2] -0.79043 -0.57343 -0.373913 -0.18370 0.03467 +gamma[1] -0.49429 -0.29727 -0.193305 -0.10370 0.14106 +gamma[2] -0.12009 -0.03013 0.092282 0.23293 0.41927 +sd 0.08385 0.24992 0.315429 0.41433 0.86084

The predicted treatment benefit for a new patient with covariates w1 = 1.6 and w2 = 1.3 is given as:

@@ -835,10 +835,10 @@

round(treatment.effect(ipd2, samples, newpatient = c(w1 = 1.6, w2 = 1.3)), 2)
0.025   0.5 0.975 
- 0.65  1.08  1.93 
+ 0.30 0.60 1.29
-

In other words, the aforementioned patient 1.08 (95% Credibility Interval: 0.65 to 1.93)

+

In other words, the aforementioned patient 0.6 (95% Credibility Interval: 0.3 to 1.29)

@@ -853,13 +853,13 @@

ds3 <- generate_ipdnma_example(type = "continuous")
 head(ds3)
-
  studyid treat          z1         z2  y
-1       1     2 -0.58562548 -0.7293231  8
-2       1     1 -0.03621696  0.6291016 11
-3       1     1  1.65265173 -0.8750261 11
-4       1     1  2.00171606 -1.0519276 11
-5       1     1 -1.06157061  0.5212684 11
-6       1     1 -0.02835944  0.4339892 11
+
  studyid treat         z1         z2  y
+1       1     2  0.8257795  0.7993777  8
+2       1     2  1.2084989  0.7265650  8
+3       1     2 -0.1500272  0.2549846  8
+4       1     1  1.2103609 -0.4187725 11
+5       1     2 -0.7352842  0.6690007  9
+6       1     1  0.4432094 -0.1226550 11

Let us look into the data a bit in more detail:

@@ -881,11 +881,11 @@

1
-(N=341)
+(N=328)
2
-(N=348)
+(N=358) 3
-(N=311)
+(N=314) Overall
(N=1000)
@@ -900,17 +900,17 @@

Mean (SD) --0.0264 (0.996) --0.0351 (1.03) -0.0866 (1.00) -0.00572 (1.01) +0.108 (1.05) +-0.0196 (1.03) +0.0531 (0.999) +0.0451 (1.03) Median [Min, Max] --0.0520 [-3.08, 2.84] --0.0398 [-2.68, 3.05] -0.0133 [-3.32, 3.26] --0.0303 [-3.32, 3.26] +0.0770 [-2.24, 3.51] +-0.0210 [-3.19, 2.84] +0.0176 [-2.82, 2.59] +0.0163 [-3.19, 3.51] z2 @@ -921,17 +921,17 @@

Mean (SD) --0.00628 (0.962) --0.0191 (1.01) --0.0157 (1.04) --0.0137 (1.00) +0.0505 (0.955) +-0.125 (1.06) +0.0315 (1.01) +-0.0183 (1.01) Median [Min, Max] -0.0476 [-2.56, 2.75] --0.0667 [-3.14, 2.46] --0.0628 [-3.23, 3.46] --0.00601 [-3.23, 3.46] +-0.00987 [-2.88, 2.61] +-0.0897 [-2.99, 2.60] +0.0626 [-2.88, 2.26] +-0.0261 [-2.99, 2.61] studyid @@ -942,72 +942,72 @@

1 -47 (13.8%) -53 (15.2%) +47 (14.3%) +53 (14.8%) 0 (0%) 100 (10.0%) 2 -56 (16.4%) -44 (12.6%) +49 (14.9%) +51 (14.2%) 0 (0%) 100 (10.0%) 3 -43 (12.6%) -57 (16.4%) +45 (13.7%) +55 (15.4%) 0 (0%) 100 (10.0%) 4 -52 (15.2%) +46 (14.0%) 0 (0%) -48 (15.4%) +54 (17.2%) 100 (10.0%) 5 -45 (13.2%) +44 (13.4%) 0 (0%) -55 (17.7%) +56 (17.8%) 100 (10.0%) 6 0 (0%) -46 (13.2%) -54 (17.4%) +54 (15.1%) +46 (14.6%) 100 (10.0%) 7 0 (0%) -42 (12.1%) -58 (18.6%) +48 (13.4%) +52 (16.6%) 100 (10.0%) 8 -32 (9.4%) -30 (8.6%) -38 (12.2%) +29 (8.8%) +34 (9.5%) +37 (11.8%) 100 (10.0%) 9 -34 (10.0%) -39 (11.2%) -27 (8.7%) +32 (9.8%) +32 (8.9%) +36 (11.5%) 100 (10.0%) 10 -32 (9.4%) -37 (10.6%) -31 (10.0%) +36 (11.0%) +31 (8.7%) +33 (10.5%) 100 (10.0%) @@ -1078,7 +1078,7 @@

+<environment: 0x55f006fab7a0>
samples <- ipd.run(ipd3, n.chains = 2, n.iter = 20, 
                    pars.save = c("alpha", "beta", "delta", "sd", "gamma"))
@@ -1105,54 +1105,54 @@

+ 2.5% 25% 50% 75% 97.5% +alpha[1] 10.875908 10.92211 10.9475 10.9751 10.9946 +alpha[2] 7.931808 7.99402 8.0203 8.0663 8.1354 +alpha[3] 10.429312 10.49357 10.5260 10.5596 10.5969 +alpha[4] 9.540423 9.56995 9.5937 9.6241 9.6622 +alpha[5] 12.907860 12.97286 12.9846 13.0158 13.0753 +alpha[6] 13.096715 13.14635 13.1720 13.2066 13.2449 +alpha[7] 7.251988 7.30633 7.3608 7.3976 7.4466 +alpha[8] 11.012250 11.06480 11.0897 11.1216 11.1917 +alpha[9] 10.051419 10.09225 10.1235 10.1512 10.2105 +alpha[10] 9.169217 9.21229 9.2374 9.2677 9.3169 +beta[1] 0.159873 0.18048 0.1935 0.2020 0.2207 +beta[2] 0.267644 0.29070 0.2992 0.3130 0.3490 +delta[1] 0.000000 0.00000 0.0000 0.0000 0.0000 +delta[2] -3.098316 -3.05326 -3.0418 -3.0307 -2.9669 +delta[3] -1.317718 -1.24606 -1.2350 -1.2225 -1.1657 +gamma[1,1] 0.000000 0.00000 0.0000 0.0000 0.0000 +gamma[2,1] -0.665029 -0.62873 -0.6114 -0.5954 -0.5733 +gamma[3,1] -0.395346 -0.36931 -0.3508 -0.3252 -0.2958 +gamma[1,2] 0.000000 0.00000 0.0000 0.0000 0.0000 +gamma[2,2] 0.514378 0.55996 0.5898 0.6053 0.6207 +gamma[3,2] 0.376606 0.40579 0.4315 0.4447 0.4669 +sd 0.008162 0.01524 0.0579 0.1150 0.1807

As before, we can use the treatment.effect() function of bipd to estimate relative effects for new patients.

@@ -1161,11 +1161,11 @@

$`treatment 2`
     0.025       0.5     0.975 
--2.515622 -2.374636 -2.277547 
+-2.605809 -2.444450 -2.295272 
 
 $`treatment 3`
      0.025        0.5      0.975 
--0.6654101 -0.5668239 -0.4414406 
+-0.8007046 -0.7261727 -0.5757139

This gives us the relative effects for all treatments versus the reference. To obtain relative effects between active treatments we need some more coding:

@@ -1182,7 +1182,7 @@

samples.all$gamma.3.2.*newpatient[2]) )
-
[1] -1.798048
+
[1] -1.724038
quantile(samples.all$delta.2.+samples.all$gamma.2.1.*
            newpatient[1]+samples.all$gamma.2.2.*newpatient[2]
@@ -1191,7 +1191,7 @@ 

, probs = 0.025)

     2.5% 
--1.928005 
+-1.876105
quantile(samples.all$delta.2.+samples.all$gamma.2.1.*
            newpatient[1]+samples.all$gamma.2.2.*newpatient[2]
@@ -1200,7 +1200,7 @@ 

, probs = 0.975)

    97.5% 
--1.658725 
+-1.619372
@@ -1226,9 +1226,9 @@

          
            s1 s2 s3
-  treat A: 49 42 33
-  treat B: 51  0 34
-  treat C:  0 58 33
+ treat A: 50 59 36 + treat B: 50 0 31 + treat C: 0 41 33 @@ -1357,18 +1357,18 @@

study 1 --2.954 (SE = 0.049 ) +-3.017 (SE = 0.055 ) study 2 --0.978 (SE = 0.050 ) +-1.168 (SE = 0.060 ) study 3 --2.949 (SE = 0.075 ) --1.143 (SE = 0.074 ) +-2.975 (SE = 0.071 ) +-0.927 (SE = 0.067 ) @@ -1434,23 +1434,23 @@

+delta[2] -3.1151 -3.0530 -3.0253 -2.9950 -2.9078 +delta[3] -1.2100 -1.1513 -1.1256 -1.0911 -1.0281 +gamma[1,1] -1.0339 -0.9435 -0.9025 -0.8749 -0.8065 +gamma[2,1] 0.6784 0.7829 0.8197 0.8547 0.9202 +gamma[1,2] -0.7334 -0.6541 -0.6266 -0.5889 -0.5287 +gamma[2,2] 0.2701 0.3133 0.3487 0.3801 0.4227
# calculate  treatment effects
 samples.all = data.frame(rbind(samps4.3[[1]], samps4.3[[2]]))
@@ -1461,21 +1461,21 @@ 

samples.all$gamma.2.1.*newpatient[2] )

-
[1] -2.096024
+
[1] -2.282333
quantile(samples.all$delta.2.+samples.all$gamma.1.1.*newpatient[1]+
            samples.all$gamma.2.1.*newpatient[2]
          , probs = 0.025)
-
    2.5% 
--2.27708 
+
     2.5% 
+-2.640549 
quantile(samples.all$delta.2.+samples.all$gamma.1.1.*newpatient[1]+
            samples.all$gamma.2.1.*newpatient[2]
          , probs = 0.975)
    97.5% 
--1.855506 
+-2.014692
diff --git a/chapter_16_files/figure-html/fig-predben_continuous_outcome-1.png b/chapter_16_files/figure-html/fig-predben_continuous_outcome-1.png index e067eb80517a0ab3f7c16e05840e01963c735eb3..9107c486a0840854a4d2c24254f9a5d2e4ca1598 100644 GIT binary patch literal 67590 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 literal 69140 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≠=YU|TA(5Nb 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 first load all relevant functions for this chapter.

Subsequently, we use the function simcountdata() to generate an example dataset with a sample size of N=2000. In this example, we have two disease modifying therapies (DMT1 and DMT0) and the outcome is the number of post-treatment multiple sclerosis relapses during follow-up.

-
# Randomization seed
-base.seed <- 999
-
-set.seed(base.seed)
-df.ori <- simcountdata(n = 2000,
-                       seed = 63,
-                       beta = c(log(0.4), log(0.5), log(1), log(1.1), log(1.2)),
-                       beta.x = c(-1.54, -0.01, 0.06, 0.25, 0.5, 0.13, 0.0000003)
-)$data
+
# Randomization seed
+base.seed <- 999
+
+set.seed(base.seed)
+df.ori <- simcountdata(n = 2000,
+                       seed = 63,
+                       beta = c(log(0.4), log(0.5), log(1), log(1.1), log(1.2)),
+                       beta.x = c(-1.54, -0.01, 0.06, 0.25, 0.5, 0.13, 0.0000003)
+)$data
Thank you for using fastDummies!
@@ -333,7 +329,7 @@

The dataset looks as follows:

-
head(df.ori)
+
head(df.ori)
  trt ageatindex_centered female prerelapse_num prevDMTefficacy premedicalcost
 1   0                   2      0              2    Low efficacy        4606.04
@@ -522,76 +518,76 @@ 

We now define key constants for the case study.

-
# Baseline characteristics
-covars <- c("age.z", "female", "prevtrtB", "prevtrtC", "prevnumsymp1", 
-            "prevnumsymp2p", "previous_cost.z", "previous_number_relapses")
-
-# Precision medicine methods to be used
-pm.methods <- c("all1", "all0", "poisson", "dWOLS", "listDTR2", 
-                "contrastReg")
-
-# Precision medicine method labels
-method.vec <- c("All 0", "All 1", "Poisson", "dWOLS", 
-                "Contrast\n Regression", "List DTR\n (2 branches)")
-
-# Number of folds in each CV iteration
-n.fold <- 5
-
-# Number of CV iterations
-n.cv <- 10
-
-# Sample size of the large independent test set to get true value
-big.n <- 100000
-
-# Define formula for the CATE model
-cate.formula <- as.formula(paste0("y ~", paste0(covars, collapse = "+"), 
-                                  "+ offset(log(years))"))
-
-# Define formula for the propensity score model
-ps.formula <- trt ~ age.z + prevtrtB + prevtrtC
-
-# Color
-myblue <- rgb(37, 15, 186, maxColorValue = 255)
-mygreen <- rgb(109, 173, 70, maxColorValue = 255)
-mygrey <- rgb(124, 135, 142, maxColorValue = 255)
+
# Baseline characteristics
+covars <- c("age.z", "female", "prevtrtB", "prevtrtC", "prevnumsymp1", 
+            "prevnumsymp2p", "previous_cost.z", "previous_number_relapses")
+
+# Precision medicine methods to be used
+pm.methods <- c("all1", "all0", "poisson", "dWOLS", "listDTR2", 
+                "contrastReg")
+
+# Precision medicine method labels
+method.vec <- c("All 0", "All 1", "Poisson", "dWOLS", 
+                "Contrast\n Regression", "List DTR\n (2 branches)")
+
+# Number of folds in each CV iteration
+n.fold <- 5
+
+# Number of CV iterations
+n.cv <- 10
+
+# Sample size of the large independent test set to get true value
+big.n <- 100000
+
+# Define formula for the CATE model
+cate.formula <- as.formula(paste0("y ~", paste0(covars, collapse = "+"), 
+                                  "+ offset(log(years))"))
+
+# Define formula for the propensity score model
+ps.formula <- trt ~ age.z + prevtrtB + prevtrtC
+
+# Color
+myblue <- rgb(37, 15, 186, maxColorValue = 255)
+mygreen <- rgb(109, 173, 70, maxColorValue = 255)
+mygrey <- rgb(124, 135, 142, maxColorValue = 255)

The data need to be preprocessed to be more analyzable. We recategorized treatment, previous treatment, and number of symptoms; scaled medical cost and age; and standardized the data.

-
df <- df.ori %>%
-  rename(previous_treatment = prevDMTefficacy,
-         age = ageatindex_centered,
-         y = postrelapse_num,
-         previous_number_relapses = prerelapse_num,
-         previous_number_symptoms = numSymptoms,
-         previous_cost = premedicalcost) %>%
-  mutate(previous_treatment = factor(previous_treatment, 
-                                     levels = c("None", 
-                                                "Low efficacy", 
-                                                "Medium and high efficacy"), 
-                                     labels = c("drugA", "drugB", "drugC")),
-         previous_number_symptoms = factor(previous_number_symptoms, 
-                                           levels = c("0", "1", ">=2"), 
-                                           labels = c("0", "1", ">=2")),
-         trt = factor(trt, levels = c(0, 1), labels = c("drug0", "drug1")),
-         previous_cost.z = scale(log(previous_cost), scale = TRUE), 
-         age.z = age + 48,
-         age.z = scale(age.z, scale = TRUE),
-         years = finalpostdayscount / 365.25,
-         mlogarr0001 = -log(y / years + 0.001),
-         drug1 = as.numeric(trt == "drug1"),
-         prevtrtB = as.numeric(previous_treatment == "drugB"),
-         prevtrtC = as.numeric(previous_treatment == "drugC"),
-         prevnumsymp1 = as.numeric(previous_number_symptoms == "1"),
-         prevnumsymp2p = as.numeric(previous_number_symptoms == ">=2")) %>%
-  dplyr::select(age.z, female, contains("prevtrt"), previous_cost.z, 
-                contains("prevnumsymp"), 
-                previous_number_relapses, trt, drug1, y, 
-                mlogarr0001, years, Iscore)
-
-# Standardize data
-z.labels <- c("age.z", "previous_cost.z")
-df.s <- df
-df.s[, setdiff(covars, z.labels)] <- df[, setdiff(covars, z.labels)]
+
df <- df.ori %>%
+  rename(previous_treatment = prevDMTefficacy,
+         age = ageatindex_centered,
+         y = postrelapse_num,
+         previous_number_relapses = prerelapse_num,
+         previous_number_symptoms = numSymptoms,
+         previous_cost = premedicalcost) %>%
+  mutate(previous_treatment = factor(previous_treatment, 
+                                     levels = c("None", 
+                                                "Low efficacy", 
+                                                "Medium and high efficacy"), 
+                                     labels = c("drugA", "drugB", "drugC")),
+         previous_number_symptoms = factor(previous_number_symptoms, 
+                                           levels = c("0", "1", ">=2"), 
+                                           labels = c("0", "1", ">=2")),
+         trt = factor(trt, levels = c(0, 1), labels = c("drug0", "drug1")),
+         previous_cost.z = scale(log(previous_cost), scale = TRUE), 
+         age.z = age + 48,
+         age.z = scale(age.z, scale = TRUE),
+         years = finalpostdayscount / 365.25,
+         mlogarr0001 = -log(y / years + 0.001),
+         drug1 = as.numeric(trt == "drug1"),
+         prevtrtB = as.numeric(previous_treatment == "drugB"),
+         prevtrtC = as.numeric(previous_treatment == "drugC"),
+         prevnumsymp1 = as.numeric(previous_number_symptoms == "1"),
+         prevnumsymp2p = as.numeric(previous_number_symptoms == ">=2")) %>%
+  dplyr::select(age.z, female, contains("prevtrt"), previous_cost.z, 
+                contains("prevnumsymp"), 
+                previous_number_relapses, trt, drug1, y, 
+                mlogarr0001, years, Iscore)
+
+# Standardize data
+z.labels <- c("age.z", "previous_cost.z")
+df.s <- df
+df.s[, setdiff(covars, z.labels)] <- df[, setdiff(covars, z.labels)]
@@ -599,156 +595,156 @@

Zhao et al. (2013) and Yadlowsky et al. (2020).

-
library(listdtr)
-
-# Estimated ITR based on the listDTR method with 2 branches
-modlist2 <- listdtr(y = df$mlogarr, # larger is more favorable
-                   a = df$drug1,
-                   x = df[, c("age.z", "female", "prevtrtB", 
-                              "prevtrtC", "previous_cost.z",
-                              "prevnumsymp1", "prevnumsymp2p", 
-                              "previous_number_relapses")],
-                   stage.x = rep(1, 8), maxlen = 2L) # somewhat slow
-
-# Estimated ITR based on the listDTR method with 3 branches
-modlist3 <- listdtr(y = df$mlogarr,
-                    a = df$drug1,
-                    x = df[, c("age.z", "female", "prevtrtB", 
-                               "prevtrtC", "previous_cost.z", 
-                               "prevnumsymp1", "prevnumsymp2p", 
-                               "previous_number_relapses")],
-                    stage.x = rep(1, 8), maxlen = 3L) # somewhat slow
-
-# Estimated CATE score based on the Poisson and contrast regression 
-modpm <- catefit(response = "count",
-            cate.model = cate.formula,
-            ps.model = ps.formula,
-            data = df,
-            higher.y = FALSE,
-            score.method = c("poisson", "contrastReg"),
-            initial.predictor.method = "poisson",
-            seed = 999)
-
-# Estimated CATE score based on the Poisson and contrast regression 
-# (based on the scaled data so the coefficients are easier to compare)
-modpm.s <- catefit(response = "count",
-              cate.model = cate.formula,
-              ps.model = ps.formula,
-              data = df.s,
-              higher.y = FALSE,
-              score.method = c("poisson", "contrastReg"),
-              initial.predictor.method = "poisson",
-              seed = 999)
+
library(listdtr)
+
+# Estimated ITR based on the listDTR method with 2 branches
+modlist2 <- listdtr(y = df$mlogarr, # larger is more favorable
+                   a = df$drug1,
+                   x = df[, c("age.z", "female", "prevtrtB", 
+                              "prevtrtC", "previous_cost.z",
+                              "prevnumsymp1", "prevnumsymp2p", 
+                              "previous_number_relapses")],
+                   stage.x = rep(1, 8), maxlen = 2L) # somewhat slow
+
+# Estimated ITR based on the listDTR method with 3 branches
+modlist3 <- listdtr(y = df$mlogarr,
+                    a = df$drug1,
+                    x = df[, c("age.z", "female", "prevtrtB", 
+                               "prevtrtC", "previous_cost.z", 
+                               "prevnumsymp1", "prevnumsymp2p", 
+                               "previous_number_relapses")],
+                    stage.x = rep(1, 8), maxlen = 3L) # somewhat slow
+
+# Estimated CATE score based on the Poisson and contrast regression 
+modpm <- catefit(response = "count",
+            cate.model = cate.formula,
+            ps.model = ps.formula,
+            data = df,
+            higher.y = FALSE,
+            score.method = c("poisson", "contrastReg"),
+            initial.predictor.method = "poisson",
+            seed = 999)
+
+# Estimated CATE score based on the Poisson and contrast regression 
+# (based on the scaled data so the coefficients are easier to compare)
+modpm.s <- catefit(response = "count",
+              cate.model = cate.formula,
+              ps.model = ps.formula,
+              data = df.s,
+              higher.y = FALSE,
+              score.method = c("poisson", "contrastReg"),
+              initial.predictor.method = "poisson",
+              seed = 999)

For results in Sections 4 and 5, we applied cross validation to mitigate over-fitting. For this chapter, we created our own customized function cvvalue() to estimate the ITR and calculate the estimated value function via cross validation for all methods, including the fixed method. The results were all saved under the prefix cvmod. The precmed package has a built-in cross validation procedure for CATE estimation so we used the function catefit().

-
# Run cross validation for each method (used for Sections 4 & 5)
-  
-## Estimated CATE scores based on the Poisson and contrast regression with cross-validation
-modcv <- catecv(response = "count",
-                cate.model = cate.formula,
-                ps.model = ps.formula,
-                data = df,
-                higher.y = FALSE,
-                score.method = c("poisson", "contrastReg"),
-                initial.predictor.method = "poisson",
-                cv.n = n.cv,
-                plot.gbmperf = FALSE,
-                seed = 999) # somewhat slow
-
-## Estimated value function for each method
-cvmodall0 <- cvvalue(data = df, xvar = covars,
-                     method = "all0", n.fold = n.fold, n.cv = n.cv, 
-                     seed = base.seed)
-
-cvmodall1 <- cvvalue(data = df, xvar = covars,
-                     method = "all1", n.fold = n.fold, n.cv = n.cv, 
-                     seed = base.seed)
-
-cvmoddwols <- cvvalue(data = df, xvar = covars,
-                      method = "dWOLS", n.fold = n.fold, n.cv = n.cv, 
-                      seed = base.seed)
-
-cvmodpois <- cvvalue(data = df, xvar = covars,
-                     method = "poisson", n.fold = n.fold, n.cv = n.cv, 
-                     seed = base.seed)
-
-cvmodlist2 <- cvvalue(data = df, xvar = covars,
-                      method = "listDTR2", n.fold = n.fold, n.cv = n.cv, 
-                      seed = base.seed) # very slow
-
-cvmodcontrastreg <- cvvalue(data = df, xvar = covars,
-                            method = "contrastReg", n.fold = n.fold, 
-                            n.cv = n.cv, 
-                            seed = base.seed) # very slow
+
# Run cross validation for each method (used for Sections 4 & 5)
+  
+## Estimated CATE scores based on the Poisson and contrast regression with cross-validation
+modcv <- catecv(response = "count",
+                cate.model = cate.formula,
+                ps.model = ps.formula,
+                data = df,
+                higher.y = FALSE,
+                score.method = c("poisson", "contrastReg"),
+                initial.predictor.method = "poisson",
+                cv.n = n.cv,
+                plot.gbmperf = FALSE,
+                seed = 999) # somewhat slow
+
+## Estimated value function for each method
+cvmodall0 <- cvvalue(data = df, xvar = covars,
+                     method = "all0", n.fold = n.fold, n.cv = n.cv, 
+                     seed = base.seed)
+
+cvmodall1 <- cvvalue(data = df, xvar = covars,
+                     method = "all1", n.fold = n.fold, n.cv = n.cv, 
+                     seed = base.seed)
+
+cvmoddwols <- cvvalue(data = df, xvar = covars,
+                      method = "dWOLS", n.fold = n.fold, n.cv = n.cv, 
+                      seed = base.seed)
+
+cvmodpois <- cvvalue(data = df, xvar = covars,
+                     method = "poisson", n.fold = n.fold, n.cv = n.cv, 
+                     seed = base.seed)
+
+cvmodlist2 <- cvvalue(data = df, xvar = covars,
+                      method = "listDTR2", n.fold = n.fold, n.cv = n.cv, 
+                      seed = base.seed) # very slow
+
+cvmodcontrastreg <- cvvalue(data = df, xvar = covars,
+                            method = "contrastReg", n.fold = n.fold, 
+                            n.cv = n.cv, 
+                            seed = base.seed) # very slow

As a next step, we need to combine all estimated ITRs and value functions:

-
# Combine CV results
-# Read in each CV result in a loop
-vhats.dhat <- dhats <- NULL
-mod_names <- c("cvmodall1", "cvmodall0", "cvmoddwols", "cvmodpois", "cvmodcontrastreg", "cvmodlist2")
-for (mod in mod_names) {
-  thismod <- get(mod)
-  for (name in names(thismod)) {
-    # Get estimated values, vhat.dhat
-    vhats.dhat <- rbind(vhats.dhat,
-                        thismod[[name]] %>%
-                          map_df(~bind_rows(names(.x) %>% str_detect("vhat.dhat") %>% keep(.x, .)), .id = "fold") %>%
-                          mutate(method = mod, cv.i = name))
-    # Get estimated rule from CV test fold, dhat
-    dhats  <- rbind(dhats,
-                    thismod[[name]] %>%
-                      map_df(~bind_rows(names(.x) %>% str_detect("^dhat$") %>% keep(.x, .)), .id = "fold") %>%
-                      mutate(method = mod, cv.i = name))
-
-  }
-}
-
-# One time run to get true optimal and worst value
-# Simulated data only
-trueV <- getTrueOptimalValue(n = big.n, seed = base.seed)
-trueWorstV <- getTrueWorstValue(n = big.n, seed = base.seed)
-
-# Preprocess
-vhats.dhat %<>%
-  mutate(V = U/W,
-         VR = (U/W - trueWorstV) / (trueV - trueWorstV)) %>%
-  group_by(method) %>%
-  summarize(n.batches = n(),
-            n.nonnaU = sum(!is.na(U)),
-            n.nonnaW = sum(!is.na(W)),
-            meanV = mean(V, na.rm = T),
-            sdV = sd(V, na.rm = T),
-            meanVR = mean(VR, na.rm = T),
-            sdVR = sd(VR, na.rm = T),
-            .groups = "keep") %>%
-  ungroup %>%
-  arrange(desc(meanV)) %>%
-  mutate(method = case_when(
-    method == "cvmodcontrastreg" ~ "Contrast\n Regression",
-    method == "cvmodall0" ~ "All 0",
-    method == "cvmodall1" ~ "All 1",
-    method == "cvmodlist2" ~ "List DTR\n (2 branches)",
-    method == "cvmoddwols" ~ "dWOLS",
-    method == "cvmodpois" ~ "Poisson"),
-    method = factor(method,
-                    levels = method.vec,
-                    labels = method.vec)
-  )
-
-dhats %<>%
-  mutate(method = case_when(
-    method == "cvmodcontrastreg" ~ "Contrast\n Regression",
-    method == "cvmodall0" ~ "All 0",
-    method == "cvmodall1" ~ "All 1",
-    method == "cvmodlist2" ~ "List DTR\n (2 branches)",
-    method == "cvmoddwols" ~ "dWOLS",
-    method == "cvmodpois" ~ "Poisson"),
-    method = factor(method,
-                    levels = method.vec,
-                    labels = method.vec)
-  )
+
# Combine CV results
+# Read in each CV result in a loop
+vhats.dhat <- dhats <- NULL
+mod_names <- c("cvmodall1", "cvmodall0", "cvmoddwols", "cvmodpois", "cvmodcontrastreg", "cvmodlist2")
+for (mod in mod_names) {
+  thismod <- get(mod)
+  for (name in names(thismod)) {
+    # Get estimated values, vhat.dhat
+    vhats.dhat <- rbind(vhats.dhat,
+                        thismod[[name]] %>%
+                          map_df(~bind_rows(names(.x) %>% str_detect("vhat.dhat") %>% keep(.x, .)), .id = "fold") %>%
+                          mutate(method = mod, cv.i = name))
+    # Get estimated rule from CV test fold, dhat
+    dhats  <- rbind(dhats,
+                    thismod[[name]] %>%
+                      map_df(~bind_rows(names(.x) %>% str_detect("^dhat$") %>% keep(.x, .)), .id = "fold") %>%
+                      mutate(method = mod, cv.i = name))
+
+  }
+}
+
+# One time run to get true optimal and worst value
+# Simulated data only
+trueV <- getTrueOptimalValue(n = big.n, seed = base.seed)
+trueWorstV <- getTrueWorstValue(n = big.n, seed = base.seed)
+
+# Preprocess
+vhats.dhat %<>%
+  mutate(V = U/W,
+         VR = (U/W - trueWorstV) / (trueV - trueWorstV)) %>%
+  group_by(method) %>%
+  summarize(n.batches = n(),
+            n.nonnaU = sum(!is.na(U)),
+            n.nonnaW = sum(!is.na(W)),
+            meanV = mean(V, na.rm = T),
+            sdV = sd(V, na.rm = T),
+            meanVR = mean(VR, na.rm = T),
+            sdVR = sd(VR, na.rm = T),
+            .groups = "keep") %>%
+  ungroup %>%
+  arrange(desc(meanV)) %>%
+  mutate(method = case_when(
+    method == "cvmodcontrastreg" ~ "Contrast\n Regression",
+    method == "cvmodall0" ~ "All 0",
+    method == "cvmodall1" ~ "All 1",
+    method == "cvmodlist2" ~ "List DTR\n (2 branches)",
+    method == "cvmoddwols" ~ "dWOLS",
+    method == "cvmodpois" ~ "Poisson"),
+    method = factor(method,
+                    levels = method.vec,
+                    labels = method.vec)
+  )
+
+dhats %<>%
+  mutate(method = case_when(
+    method == "cvmodcontrastreg" ~ "Contrast\n Regression",
+    method == "cvmodall0" ~ "All 0",
+    method == "cvmodall1" ~ "All 1",
+    method == "cvmodlist2" ~ "List DTR\n (2 branches)",
+    method == "cvmoddwols" ~ "dWOLS",
+    method == "cvmodpois" ~ "Poisson"),
+    method = factor(method,
+                    levels = method.vec,
+                    labels = method.vec)
+  )

@@ -759,40 +755,40 @@

10.3.1.1 listDTR

If the PM method already has built-in visualization (especially for tree-based methods), we can visualize the ITR directly. For example, we can simply use the function plot() to visualize the estimated ITR with the listDTR method.

-
#modlist3 %>% plot()
+
#modlist3 %>% plot()

We can also create our own visualization like Figure 1A in the chapter.

-
df.list3 <- df %>%
-  mutate(d.list = ifelse(age.z > 0.599 | prevtrtB > 0.5, "Recommend 1", "Recommend 0"), # based on modlist3
-         Rule = factor(as.character(d.list), levels = c("Recommend 0", "Recommend 1")),
-         prevtrtB = ifelse(prevtrtB == 1, "Previous treatment is drug B", "Previous treatment is not drug B")
-  )
-
-## Figure 1A
-df.list3 %>%
-  ggplot(aes(x = age.z, fill = Rule))+
-  geom_histogram(position = position_dodge2(preserve = 'single'), binwidth = 0.1)+
-  facet_wrap(~ prevtrtB, nrow = 2) +
-  scale_fill_brewer(palette = "Set1") +
-  labs(x = "Standardized age", y = "Count") +
-  theme_classic() +
-  theme(legend.position = 'top', text = element_text(size = 20))
+
df.list3 <- df %>%
+  mutate(d.list = ifelse(age.z > 0.599 | prevtrtB > 0.5, "Recommend 1", "Recommend 0"), # based on modlist3
+         Rule = factor(as.character(d.list), levels = c("Recommend 0", "Recommend 1")),
+         prevtrtB = ifelse(prevtrtB == 1, "Previous treatment is drug B", "Previous treatment is not drug B")
+  )
+
+## Figure 1A
+df.list3 %>%
+  ggplot(aes(x = age.z, fill = Rule))+
+  geom_histogram(position = position_dodge2(preserve = 'single'), binwidth = 0.1)+
+  facet_wrap(~ prevtrtB, nrow = 2) +
+  scale_fill_brewer(palette = "Set1") +
+  labs(x = "Standardized age", y = "Count") +
+  theme_classic() +
+  theme(legend.position = 'top', text = element_text(size = 20))

The subgroup-level annualized relapse rate (ARR) can be calculated based on the listDTR ITR:

-
df.list3 %>%
-  group_by(trt, d.list) %>%
-  summarise(ARR = round(sum(y) / sum(years), 2),
-            n = n(),
-            `prop%` = round(n / nrow(df), 2)*100, .groups = "drop") %>%
-  rename("listDTR ITR" = d.list,
-         "Observed treatment" = trt) %>%
-  kable() %>%
-  kable_styling(full_width = F)
+
df.list3 %>%
+  group_by(trt, d.list) %>%
+  summarise(ARR = round(sum(y) / sum(years), 2),
+            n = n(),
+            `prop%` = round(n / nrow(df), 2)*100, .groups = "drop") %>%
+  rename("listDTR ITR" = d.list,
+         "Observed treatment" = trt) %>%
+  kable() %>%
+  kable_styling(full_width = F)
@@ -845,13 +841,13 @@

10.3.1.2 Score-based method

Although some PM methods do not have built-in visualization or not as “white-box” as some more interpretable methods, there still might be ways to visualize the ITR. For example, score-based methods (such as Poisson and contrast regression) produce an estimate of the CATE score for each patient, and a classification tree can be fitted on these scores and visualized. Below is a histogram-density plot of the CATE scores estimated from the Poisson regression and the fitted classification tree using the estimated CATE scores. We pruned the tree so it only had three nodes for simplicity. The rpart.plot package has a built-in visualization function of the rpart model, rpart.plot(), which is how Figure 1B in the chapter was generated.

-
df["score.poisson"] <- modpm$score.poisson
-
-ggplot(df, aes(x = score.poisson)) + 
-  geom_histogram(aes(y = ..density..), colour = "black", fill = "lightblue") +
-  geom_density(alpha = .2, fill = "white") +
-  labs(x = "Estimated CATE score from the Poisson regression", y = "Density") + 
-  theme_classic()
+
df["score.poisson"] <- modpm$score.poisson
+
+ggplot(df, aes(x = score.poisson)) + 
+  geom_histogram(aes(y = ..density..), colour = "black", fill = "lightblue") +
+  geom_density(alpha = .2, fill = "white") +
+  labs(x = "Estimated CATE score from the Poisson regression", y = "Density") + 
+  theme_classic()
Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
 ℹ Please use `after_stat(density)` instead.
@@ -862,15 +858,15 @@

-
modtree <- rpart(as.formula(paste0("score.poisson ~", paste0(covars, collapse = "+"))),
-                 method = "anova", data = df, control = rpart.control(minsplit = 100, cp = 0.01)) # Fit Poisson CATE scores on a classification tree
-
-modtree.pr <- prune(modtree, cp = 0.09) # I ended up choosing a higher cp value to have only 3 subgroups
-
-# print(rpart.rules(modtree.pr, cover = TRUE))
-
-## Figure 1B
-rpart.plot(modtree.pr, box.palette = "RdBu", type = 5, under = TRUE, tweak = 1.2, compress = TRUE)
+
modtree <- rpart(as.formula(paste0("score.poisson ~", paste0(covars, collapse = "+"))),
+                 method = "anova", data = df, control = rpart.control(minsplit = 100, cp = 0.01)) # Fit Poisson CATE scores on a classification tree
+
+modtree.pr <- prune(modtree, cp = 0.09) # I ended up choosing a higher cp value to have only 3 subgroups
+
+# print(rpart.rules(modtree.pr, cover = TRUE))
+
+## Figure 1B
+rpart.plot(modtree.pr, box.palette = "RdBu", type = 5, under = TRUE, tweak = 1.2, compress = TRUE)

@@ -882,68 +878,68 @@

10.3.2 ITR accuracy

The accuracy of ITR is the proportion of patients whose estimated ITR is the same as the true optimal ITR. The estimated ITRs have been obtained from the PM methods but we need to calculate the true optimal ITR. This is only possible for simulated data where the decision boundary is known. Based on the data generating mechanism in simcountdata(), Iscore is a score generated from a linear combination of baseline covariates where lower scores represented that drug 1 was better and higher scores represented that drug 0 was better. We then classified patients in 5 equal-size subgroups based on the Iscore, where groups 1 and 2 have drug 1 as their true optimal ITR and groups 3 and 4 have drug 0 as their true optimal ITR. Group 3 is considered the neutral group, where patients are indifferent to either drug so we assign the true optimal ITR to be their observed treatment. Thus, we identify the true optimal ITR for every patient based on this subgrouping, which was derived from their true score Iscore. Since we used cross validation in estimating the ITR, we need to apply the exact same cross validation to the true optimal ITR. This is achieved by specifying the same randomization seed in the cross validation loop (see seed).

-
## Create new columns
-dhats$d <- rep(NA, nrow(dhats)) # true d
-
-# Identify the true optimal treatment
-# See simcountdata() in the function script to learn more about Iscore
-sim <- df %>%
-  mutate(trueT = ifelse(as.numeric(Iscore) < 3, 1, 0),
-         trueT = ifelse(Iscore == 3, drug1, trueT)) # neutral group
-
-# Format data
-input <- data.frame(y = sim$y, 
-                    trt = sim$drug1, 
-                    time = log(sim$years), 
-                    sim[covars])
-
-# Cross validation loop
-for (i in unique(dhats$cv.i)) {
-  seed <- base.seed*100 + as.numeric(str_extract(i, "[0-9]+"))
-  set.seed(seed)
-
-  # Create CV folds
-  folds <- createFolds(input$trt, k = n.fold, list = TRUE) 
-
-  for (fold.i in seq(n.fold)) {
-    testdata <- sim[folds[[fold.i]],]
-    # number of methods which succeeded for the given fold/batch. 
-    
-    
-    ind_result <- which(dhats$fold == paste0("fold", fold.i) & 
-                          dhats$cv.i == i & 
-                          !is.na(dhats$dhat))
-    
-    nr <- length(ind_result)
-    
-    dhats$d[ind_result] <- rep(testdata$trueT, nr/nrow(testdata))
-    stopifnot(nr %% nrow(testdata) == 0)
-  }
-} # end of all cv iterations
+
## Create new columns
+dhats$d <- rep(NA, nrow(dhats)) # true d
+
+# Identify the true optimal treatment
+# See simcountdata() in the function script to learn more about Iscore
+sim <- df %>%
+  mutate(trueT = ifelse(as.numeric(Iscore) < 3, 1, 0),
+         trueT = ifelse(Iscore == 3, drug1, trueT)) # neutral group
+
+# Format data
+input <- data.frame(y = sim$y, 
+                    trt = sim$drug1, 
+                    time = log(sim$years), 
+                    sim[covars])
+
+# Cross validation loop
+for (i in unique(dhats$cv.i)) {
+  seed <- base.seed*100 + as.numeric(str_extract(i, "[0-9]+"))
+  set.seed(seed)
+
+  # Create CV folds
+  folds <- createFolds(input$trt, k = n.fold, list = TRUE) 
+
+  for (fold.i in seq(n.fold)) {
+    testdata <- sim[folds[[fold.i]],]
+    # number of methods which succeeded for the given fold/batch. 
+    
+    
+    ind_result <- which(dhats$fold == paste0("fold", fold.i) & 
+                          dhats$cv.i == i & 
+                          !is.na(dhats$dhat))
+    
+    nr <- length(ind_result)
+    
+    dhats$d[ind_result] <- rep(testdata$trueT, nr/nrow(testdata))
+    stopifnot(nr %% nrow(testdata) == 0)
+  }
+} # end of all cv iterations

Once we identified the true optimal ITR (\(d^{opt}\)), we can calculate the accuracy in each validation fold for each PM method (\(\hat{d}_{pm}\)). Mathematically, accuracy can be expressed as \[Accuracy_{pm}(\boldsymbol{x}^{val}) = \frac{1}{n^{val}}\sum_{i = 1}^{n^{val}} I\big(\hat{d}_{pm}(\boldsymbol{x}_i^{val}) == d^{opt}(\boldsymbol{x}_i^{val})\big),\] where \(n^{val}\) is the sample size in the validation fold, \(\boldsymbol{x}_i^{val}\) is the baseline characteristics of the \(i\)th patient in the validation fold, and \(pm\) stands for one PM method.

Below is how Figure 2 in the chapter was generated. It summarized the accuracy across all validation folds as a box plot so we can also learn the variability of accuracy across folds.

-
##### Accuracy #####
-## Calculate % accuracy for each iteration & summary statistics
-dhats.accuracy <- dhats %>%
-  group_by(method, cv.i, fold) %>%
-  summarise(accuracy = sum(dhat == d)/n(), .groups = "drop") %>%
-  ungroup
-
-## Make the accuracy plot, Figure 2
-dhats.accuracy %>%
-  ggplot(aes(x = method, y = accuracy)) +
-  geom_boxplot() +
-  geom_hline(yintercept = 1, linetype = 2, linewidth = 1, color = "gray") +
-  geom_hline(yintercept = 0.5, linetype = 2, linewidth = 1, color = "gray") +
-  theme_classic() +
-  labs(x = "Method", y = "Accuracy") +
-  theme(axis.text = element_text(size = 15),
-        axis.title.y = element_text(size = 15),
-        axis.title.x = element_text(size = 15),
-        axis.text.x = element_text(angle = 0, size = 15),
-        strip.text.x = element_text(size = 15))
+
##### Accuracy #####
+## Calculate % accuracy for each iteration & summary statistics
+dhats.accuracy <- dhats %>%
+  group_by(method, cv.i, fold) %>%
+  summarise(accuracy = sum(dhat == d)/n(), .groups = "drop") %>%
+  ungroup
+
+## Make the accuracy plot, Figure 2
+dhats.accuracy %>%
+  ggplot(aes(x = method, y = accuracy)) +
+  geom_boxplot() +
+  geom_hline(yintercept = 1, linetype = 2, linewidth = 1, color = "gray") +
+  geom_hline(yintercept = 0.5, linetype = 2, linewidth = 1, color = "gray") +
+  theme_classic() +
+  labs(x = "Method", y = "Accuracy") +
+  theme(axis.text = element_text(size = 15),
+        axis.title.y = element_text(size = 15),
+        axis.title.x = element_text(size = 15),
+        axis.text.x = element_text(angle = 0, size = 15),
+        strip.text.x = element_text(size = 15))

@@ -953,33 +949,33 @@

10.3.3 ITR agreement

When we do not know the true data generating mechanism, e.g., real-world data, we cannot compare the estimated ITR with the true optimal ITR. However, we can compare the estimated ITR with another estimated ITR, and this is called agreement. Agreement is the proportion of patients whose estimated ITR of a method is the same as the estimated ITR of another method. Thus, agreement is between two methods. Mathematically, \[Agreement_{1, 2}(\boldsymbol{x}^{val}) = \frac{1}{n^{val}} \sum_{i = 1}^{n^{val}} I\big( \hat{d}_{1}(\boldsymbol{x}^{val}) == \hat{d}_{2} (\boldsymbol{x}^{val}) \big), \] where \(n^{val}\) is the sample size in the validation fold, \(\boldsymbol{x}_i^{val}\) is the baseline characteristics of the \(i\)th patient in the validation fold, and \(1, 2\) stands for method 1 and method 2.

-
##### Agreement #####
-dhats.concat <- dhats %>%
-  arrange(cv.i, fold, method) %>%
-  mutate(iteration.fold = (as.numeric(str_extract(cv.i, "[0-9]+")) - 1) * 10 + as.numeric(str_extract(fold, "[0-9]+"))) %>% 
-  dplyr::select(method, iteration.fold, dhat) %>%
-  group_by(method, iteration.fold) %>%
-  mutate(i = 1:n()) %>%  
-  ungroup
-
-m <- length(method.vec)
-dhats.agreement <- matrix(nrow = m, ncol = m)
-colnames(dhats.agreement) <- method.vec
-rownames(dhats.agreement) <- method.vec
-
-for(k in seq_len(m)){
-  for(j in seq(k, m)){
-    data.k <- dhats.concat %>% filter(method == method.vec[k])
-    data.j <- dhats.concat %>% filter(method == method.vec[j])
-    data.jk <- data.k %>% full_join(data.j, by = c("iteration.fold", "i"))
-    dhats.agreement[k, j] <- dhats.agreement[j, k] <- sum(data.jk$dhat.x == data.jk$dhat.y, na.rm = T) / sum(is.na(data.jk$dhat.x) == FALSE & is.na(data.jk$dhat.y) == FALSE)
-  }
-}
-
-# Make the agreement plot, Figure 3
-corrplot(dhats.agreement, method = "color",  type = "lower",
-         addCoef.col = "orange", number.cex = 1.5,
-         tl.cex = 1.2, cl.cex = 1.2, tl.col = "black", tl.srt = 0, tl.offset = 1.5)
+
##### Agreement #####
+dhats.concat <- dhats %>%
+  arrange(cv.i, fold, method) %>%
+  mutate(iteration.fold = (as.numeric(str_extract(cv.i, "[0-9]+")) - 1) * 10 + as.numeric(str_extract(fold, "[0-9]+"))) %>% 
+  dplyr::select(method, iteration.fold, dhat) %>%
+  group_by(method, iteration.fold) %>%
+  mutate(i = 1:n()) %>%  
+  ungroup
+
+m <- length(method.vec)
+dhats.agreement <- matrix(nrow = m, ncol = m)
+colnames(dhats.agreement) <- method.vec
+rownames(dhats.agreement) <- method.vec
+
+for(k in seq_len(m)){
+  for(j in seq(k, m)){
+    data.k <- dhats.concat %>% filter(method == method.vec[k])
+    data.j <- dhats.concat %>% filter(method == method.vec[j])
+    data.jk <- data.k %>% full_join(data.j, by = c("iteration.fold", "i"))
+    dhats.agreement[k, j] <- dhats.agreement[j, k] <- sum(data.jk$dhat.x == data.jk$dhat.y, na.rm = T) / sum(is.na(data.jk$dhat.x) == FALSE & is.na(data.jk$dhat.y) == FALSE)
+  }
+}
+
+# Make the agreement plot, Figure 3
+corrplot(dhats.agreement, method = "color",  type = "lower",
+         addCoef.col = "orange", number.cex = 1.5,
+         tl.cex = 1.2, cl.cex = 1.2, tl.col = "black", tl.srt = 0, tl.offset = 1.5)

@@ -991,39 +987,39 @@

10.4 Patient well-being

Patient well-being is evaluated via the value function, which is defined as the expected outcome had they followed the specified ITR. Like a fortune teller’s crystal ball, this metric tells us how well the patients would do on average under each ITR. We can then compare across different ITRs and identify an optimal ITR. Cross validation is necessary here to mitigate over-fitting, and we visualized the value function results as error bar plots. The mean and standard deviation of the value functions have been preprocessed previously. We use ggplot() to generate the error bar plots. Figure 4A is the original value function estimates, and Figure 4B is the standardized value ratio estimates, which convert value functions to a ratio where 1 is always more desirable.

-
##### Errorbar plot #####
-# Figure 4A
-p4a <- vhats.dhat %>%
-  ggplot(aes(x = method, y = meanV)) +
-  geom_point(size = 8, shape = 16, color = "navy") +
-  geom_errorbar(aes(ymin = meanV - sdV, ymax = meanV + sdV), width = 0.3, size = 2, position = position_dodge(0.9), color = "navy") +
-  theme_classic() + xlab("") + ylab("Cross-validated value (mean +- SD)") +
-  theme(axis.text = element_text(size = 15), axis.title.y = element_text(size = 15)) +
-  geom_hline(yintercept = vhats.dhat$meanV[which(vhats.dhat$method == "All 1")], linetype = 2, size = 1.5, color = "gray")
+
##### Errorbar plot #####
+# Figure 4A
+p4a <- vhats.dhat %>%
+  ggplot(aes(x = method, y = meanV)) +
+  geom_point(size = 8, shape = 16, color = "navy") +
+  geom_errorbar(aes(ymin = meanV - sdV, ymax = meanV + sdV), width = 0.3, size = 2, position = position_dodge(0.9), color = "navy") +
+  theme_classic() + xlab("") + ylab("Cross-validated value (mean +- SD)") +
+  theme(axis.text = element_text(size = 15), axis.title.y = element_text(size = 15)) +
+  geom_hline(yintercept = vhats.dhat$meanV[which(vhats.dhat$method == "All 1")], linetype = 2, size = 1.5, color = "gray")
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
 ℹ Please use `linewidth` instead.
-
##### Value ratio #####
-# Figure 4B
-p4b <- vhats.dhat %>%
-  dplyr::select(method, contains("VR"), n.nonnaU) %>%
-  ggplot(aes(x = method, y = meanVR)) +
-  geom_point(size = 8, color = "navy") +
-  geom_errorbar(aes(ymin = meanVR - sdVR, ymax = meanVR + sdVR), width = 0.3, size = 2, position = position_dodge(0.9), color = "navy") +
-  geom_hline(yintercept = 1, color = "gray", linetype = 2, size = 1) +
-  geom_hline(yintercept = 0, color = "gray", linetype = 2, size = 1) +
-  scale_y_continuous(breaks = seq(0, 1, length = 6)) +
-  theme_classic() +
-  labs(x = "", y = "Value ratio of cross-validated estimated decision rule (mean +- SD)") +
-  theme(axis.text = element_text(size = 13),
-        axis.title.y = element_text(size = 15),
-        axis.title.x = element_text(size = 15),
-        axis.text.x = element_text(size = 15),
-        strip.text.x = element_text(size = 12))
-
-# Figure 4
-ggarrange(p4a, p4b, ncol = 2, nrow = 1, labels = c("A", "B"))
+
##### Value ratio #####
+# Figure 4B
+p4b <- vhats.dhat %>%
+  dplyr::select(method, contains("VR"), n.nonnaU) %>%
+  ggplot(aes(x = method, y = meanVR)) +
+  geom_point(size = 8, color = "navy") +
+  geom_errorbar(aes(ymin = meanVR - sdVR, ymax = meanVR + sdVR), width = 0.3, size = 2, position = position_dodge(0.9), color = "navy") +
+  geom_hline(yintercept = 1, color = "gray", linetype = 2, size = 1) +
+  geom_hline(yintercept = 0, color = "gray", linetype = 2, size = 1) +
+  scale_y_continuous(breaks = seq(0, 1, length = 6)) +
+  theme_classic() +
+  labs(x = "", y = "Value ratio of cross-validated estimated decision rule (mean +- SD)") +
+  theme(axis.text = element_text(size = 13),
+        axis.title.y = element_text(size = 15),
+        axis.title.x = element_text(size = 15),
+        axis.text.x = element_text(size = 15),
+        strip.text.x = element_text(size = 12))
+
+# Figure 4
+ggarrange(p4a, p4b, ncol = 2, nrow = 1, labels = c("A", "B"))

@@ -1035,14 +1031,14 @@

<

10.5.1 Validation

The package we used for the two score-based methods (Poisson and contrast regression), PrecMed, has built-in visualization tools to diagnose the results: validation box plots boxplot(), validation curves plot(), and area between curves (ABC) statistics abc().

-
##### Validation of ITR scores #####
-# Figure 5A
-p5a <- boxplot(modcv, ylab = "Rate ratio between T=1 and T=0 in each subgroup")
-# Figure 5B
-p5b <- plot(modcv, ylab = "Rate ratio between T=1 and T=0 in each subgroup")
-
-# Figure 5
-ggarrange(p5a, p5b, ncol = 1, nrow = 2, labels = c("A", "B"))
+
##### Validation of ITR scores #####
+# Figure 5A
+p5a <- boxplot(modcv, ylab = "Rate ratio between T=1 and T=0 in each subgroup")
+# Figure 5B
+p5b <- plot(modcv, ylab = "Rate ratio between T=1 and T=0 in each subgroup")
+
+# Figure 5
+ggarrange(p5a, p5b, ncol = 1, nrow = 2, labels = c("A", "B"))

@@ -1053,20 +1049,20 @@

10.5.2 Univariate comparision of patient characteristics

The 60/40 cutoff was used in the chapter to split patients into “high responders” and “standard responders”. The function CreateTableOne() in the tableone package was used to generate a table comparing side-by-side the baseline characteristics between the two responder groups.

-
##### Side-by-side baseline characteristic comparison between responder subgroups #####
-cutoff <- quantile(modpm$score.poisson, 0.6) # 60/40 high vs standard responder split
-df["responder to T=1"] <- ifelse(modpm$score.poisson < cutoff, "High", "Standard")
-df["age.z"] <- as.numeric(df$age.z)
-df["previous_cost.z"] <- as.numeric(df$previous_cost.z)
-
-labs <- list("age.z" = "Standardized baseline age", "female" = "Female",
-             "prevtrtB" = "Previous treatment drug B", "prevtrtC" = "Previous treatment drug C",
-             "prevnumsymp1" = "Previous number of symptoms == 1",
-             "prevnumsymp2p" = "Previuos number of symptoms >= 2",
-             "previous_cost.z" = "Standardized previous medical cost\n(excluding medication)",
-             "previos_number_relapses" = "Previous number of relapses")
-
-tab <- CreateTableOne(vars = covars, strata = "responder to T=1", data = df, test = F) %>% print(smd = T)
+
##### Side-by-side baseline characteristic comparison between responder subgroups #####
+cutoff <- quantile(modpm$score.poisson, 0.6) # 60/40 high vs standard responder split
+df["responder to T=1"] <- ifelse(modpm$score.poisson < cutoff, "High", "Standard")
+df["age.z"] <- as.numeric(df$age.z)
+df["previous_cost.z"] <- as.numeric(df$previous_cost.z)
+
+labs <- list("age.z" = "Standardized baseline age", "female" = "Female",
+             "prevtrtB" = "Previous treatment drug B", "prevtrtC" = "Previous treatment drug C",
+             "prevnumsymp1" = "Previous number of symptoms == 1",
+             "prevnumsymp2p" = "Previuos number of symptoms >= 2",
+             "previous_cost.z" = "Standardized previous medical cost\n(excluding medication)",
+             "previos_number_relapses" = "Previous number of relapses")
+
+tab <- CreateTableOne(vars = covars, strata = "responder to T=1", data = df, test = F) %>% print(smd = T)
                                      Stratified by responder to T=1
                                        High         Standard     SMD   
@@ -1083,105 +1079,105 @@ 

-
smd <- as_tibble(tab, rownames = "var") %>%
-  rowwise() %>%
-  mutate(variable = as.factor(str_extract(var, ".*(?= \\(mean \\(SD\\)\\))"))) %>%
-  filter(!is.na(variable)) %>%
-  arrange(desc(SMD)) %>%
-  mutate(smd = paste0("SMD =", SMD),
-         variable = labs[[variable]]) %>%
-  dplyr::select(variable, smd) %>%
-  mutate(ID = 1)
-
-levels <- unique(smd$variable)
-
-p6a <- df %>%
-  mutate(ID = 1:n()) %>%
-  dplyr::select(all_of(covars), ID, contains("responder")) %>%
-  melt(id = c("ID", "responder to T=1")) %>%
-  rowwise() %>%
-  mutate(variable = labs[[variable]]) %>%
-  left_join(smd, by = c("variable", "ID")) %>%
-  mutate(variable2 = factor(variable, levels = levels)) %>%
-  ggplot(aes(x = reorder(variable2, desc(variable2)), color = `responder to T=1`, y = value, group = `responder to T=1`)) +
-  stat_summary(fun = mean, geom = "point", size = 4, position = position_dodge(width = 0.5)) +
-  stat_summary(fun.data = mean_sdl, geom = "errorbar", position = position_dodge(width = 0.5), width= 0.3, size = 1.2) +
-  geom_hline(yintercept = 0, color = "gray", linetype = "dashed") +
-  geom_text(aes(label = smd), hjust = -0.5, y = -1.5, color = "darkgray", size = 3.5) +
-  # facet_wrap(~ variable2, nrow = 4) +
-  labs(x = "Baseline patient characteristic",
-       y = "Mean +- SD") +
-  coord_flip() +
-  scale_color_brewer(palette = "Set2")  +
-  theme_classic() +
-  theme(legend.position = "top",
-        axis.text = element_text(size = 13),
-        axis.title.y = element_text(size = 15),
-        axis.title.x = element_text(size = 15),
-        axis.text.x = element_text(size = 15),
-        strip.text.x = element_text(size = 12))
-
-# Figure 6A
-ggarrange(p6a, nrow = 1, labels = c("A"))
+
smd <- as_tibble(tab, rownames = "var") %>%
+  rowwise() %>%
+  mutate(variable = as.factor(str_extract(var, ".*(?= \\(mean \\(SD\\)\\))"))) %>%
+  filter(!is.na(variable)) %>%
+  arrange(desc(SMD)) %>%
+  mutate(smd = paste0("SMD =", SMD),
+         variable = labs[[variable]]) %>%
+  dplyr::select(variable, smd) %>%
+  mutate(ID = 1)
+
+levels <- unique(smd$variable)
+
+p6a <- df %>%
+  mutate(ID = 1:n()) %>%
+  dplyr::select(all_of(covars), ID, contains("responder")) %>%
+  melt(id = c("ID", "responder to T=1")) %>%
+  rowwise() %>%
+  mutate(variable = labs[[variable]]) %>%
+  left_join(smd, by = c("variable", "ID")) %>%
+  mutate(variable2 = factor(variable, levels = levels)) %>%
+  ggplot(aes(x = reorder(variable2, desc(variable2)), color = `responder to T=1`, y = value, group = `responder to T=1`)) +
+  stat_summary(fun = mean, geom = "point", size = 4, position = position_dodge(width = 0.5)) +
+  stat_summary(fun.data = mean_sdl, geom = "errorbar", position = position_dodge(width = 0.5), width= 0.3, size = 1.2) +
+  geom_hline(yintercept = 0, color = "gray", linetype = "dashed") +
+  geom_text(aes(label = smd), hjust = -0.5, y = -1.5, color = "darkgray", size = 3.5) +
+  # facet_wrap(~ variable2, nrow = 4) +
+  labs(x = "Baseline patient characteristic",
+       y = "Mean +- SD") +
+  coord_flip() +
+  scale_color_brewer(palette = "Set2")  +
+  theme_classic() +
+  theme(legend.position = "top",
+        axis.text = element_text(size = 13),
+        axis.title.y = element_text(size = 15),
+        axis.title.x = element_text(size = 15),
+        axis.text.x = element_text(size = 15),
+        strip.text.x = element_text(size = 12))
+
+# Figure 6A
+ggarrange(p6a, nrow = 1, labels = c("A"))

We can also show the density of ITR scores obtained from the score-based methods. The results can be found in modpm and we used histogram to visualize (Figure 6B).

-
##### Density of ITR score #####
-dataplot <- data.frame(score = factor(rep(c("Naive Poisson", "Contrast Regression"),
-                                          each = length(modpm$score.poisson))),
-                       value = c(modpm$score.poisson, modpm$score.contrastReg))
-
-p6b <- dataplot %>%
-  ggplot(aes(x = value, fill = score)) +
-  geom_density(alpha = 0.5) +
-  scale_fill_manual(values = c("dodgerblue", "gray30")) +
-  geom_vline(xintercept = 0, color = "darkgray", linetype = "dashed", size = 1) +
-  labs(x = "Estimated CATE score", y = "Density", fill = "Method") +
-  theme_classic() +
-  theme(legend.position = c(0.2, 0.8),
-        axis.text = element_text(size = 13),
-        axis.title.y = element_text(size = 15),
-        axis.title.x = element_text(size = 15),
-        axis.text.x = element_text(size = 15),
-        strip.text.x = element_text(size = 12))
+
##### Density of ITR score #####
+dataplot <- data.frame(score = factor(rep(c("Naive Poisson", "Contrast Regression"),
+                                          each = length(modpm$score.poisson))),
+                       value = c(modpm$score.poisson, modpm$score.contrastReg))
+
+p6b <- dataplot %>%
+  ggplot(aes(x = value, fill = score)) +
+  geom_density(alpha = 0.5) +
+  scale_fill_manual(values = c("dodgerblue", "gray30")) +
+  geom_vline(xintercept = 0, color = "darkgray", linetype = "dashed", size = 1) +
+  labs(x = "Estimated CATE score", y = "Density", fill = "Method") +
+  theme_classic() +
+  theme(legend.position = c(0.2, 0.8),
+        axis.text = element_text(size = 13),
+        axis.title.y = element_text(size = 15),
+        axis.title.x = element_text(size = 15),
+        axis.text.x = element_text(size = 15),
+        strip.text.x = element_text(size = 12))

The ITR scores are essentially a linear combination of the baseline characteristics, thus it might be also of interest for one to know the corresponding coefficients (or weights) which shows how much each baseline variable contributed to the ITR score. To make it comparable across different scales of the baseline variables, we used the scaled data and the model result modpm.s was used to extract the coefficients and visualize as a bar plot. The coefficients can be presented in a table as well.

-
# Coefficients
-coef <- modpm.s$coefficients
-
-p6c <- coef %>%
-  as_tibble(rownames = "varname") %>%
-  melt(id.vars = "varname") %>%
-  filter(variable == "poisson", varname != "(Intercept)") %>%
-  mutate(absval = abs(value),
-         sign = ifelse(value > 0, "+", "-")) %>%
-  arrange(absval) %>%
-  mutate(varname = factor(varname, levels = unique(varname))) %>%
-  ggplot(aes(x = varname, y = absval, fill = sign)) +
-  geom_bar(stat = "identity", width = 0.5) +
-  scale_fill_brewer(palette = "Set1") +
-  scale_x_discrete(labels = labs) +
-  coord_flip() +
-  labs(y = "Absolute value of the estimated coefficient of CATE scores\nbased on Poisson regression", x = "Baseline patient characteristic") +
-  theme_minimal() +
-  theme(legend.position = c(0.8, 0.2),
-        axis.text = element_text(size = 13),
-        axis.title.y = element_text(size = 15),
-        axis.title.x = element_text(size = 15),
-        axis.text.x = element_text(size = 15),
-        strip.text.x = element_text(size = 12))
-
-# Figure 6B, 6C
-ggarrange(p6b, p6c, nrow = 2, labels = c("B", "C"))
+
# Coefficients
+coef <- modpm.s$coefficients
+
+p6c <- coef %>%
+  as_tibble(rownames = "varname") %>%
+  melt(id.vars = "varname") %>%
+  filter(variable == "poisson", varname != "(Intercept)") %>%
+  mutate(absval = abs(value),
+         sign = ifelse(value > 0, "+", "-")) %>%
+  arrange(absval) %>%
+  mutate(varname = factor(varname, levels = unique(varname))) %>%
+  ggplot(aes(x = varname, y = absval, fill = sign)) +
+  geom_bar(stat = "identity", width = 0.5) +
+  scale_fill_brewer(palette = "Set1") +
+  scale_x_discrete(labels = labs) +
+  coord_flip() +
+  labs(y = "Absolute value of the estimated coefficient of CATE scores\nbased on Poisson regression", x = "Baseline patient characteristic") +
+  theme_minimal() +
+  theme(legend.position = c(0.8, 0.2),
+        axis.text = element_text(size = 13),
+        axis.title.y = element_text(size = 15),
+        axis.title.x = element_text(size = 15),
+        axis.text.x = element_text(size = 15),
+        strip.text.x = element_text(size = 12))
+
+# Figure 6B, 6C
+ggarrange(p6b, p6c, nrow = 2, labels = c("B", "C"))

-
# Coefficients presented as a table
-coef %>% round(2) %>% kable() %>% kable_styling(full_width = F)
+
# Coefficients presented as a table
+coef %>% round(2) %>% kable() %>% kable_styling(full_width = F)
diff --git a/index.html b/index.html index 43e3f8d..8364847 100644 --- a/index.html +++ b/index.html @@ -223,7 +223,7 @@

Comparative Effectiveness and Personalized Medicine Research U
Published
-

17 December, 2023

+

18 December, 2023

diff --git a/search.json b/search.json index 12e732b..6207315 100644 --- a/search.json +++ b/search.json @@ -158,7 +158,7 @@ "href": "chapter_07.html#version-info", "title": "4  Effect Modification Analysis within the Propensity score Framework", "section": "Version info", - "text": "Version info\nThis chapter was rendered using the following version of R and its packages:\n\n\nR version 4.2.3 (2023-03-15)\nPlatform: x86_64-pc-linux-gnu (64-bit)\nRunning under: Ubuntu 22.04.3 LTS\n\nMatrix products: default\nBLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3\nLAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so\n\nlocale:\n [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8 \n [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8 \n [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C \n[10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C \n\nattached base packages:\n[1] grid stats graphics grDevices utils datasets methods \n[8] base \n\nother attached packages:\n [1] interactions_1.1.5 survey_4.2-1 survival_3.5-3 Matrix_1.6-4 \n [5] interactionR_0.1.7 simcausal_0.5.6 scales_1.3.0 ggplot2_3.4.4 \n [9] xtable_1.8-4 dplyr_1.1.4 kableExtra_1.3.4 knitr_1.45 \n[13] cowplot_1.1.2 broom_1.0.5 MatchIt_4.5.5 jtools_2.2.2 \n[17] sandwich_3.1-0 lmtest_0.9-40 zoo_1.8-12 optmatch_0.10.7 \n[21] WeightIt_0.14.2 cobalt_4.5.2 table1_1.4.3 \n\nloaded via a namespace (and not attached):\n [1] fontquiver_0.2.1 webshot_0.5.5 httr_1.4.7 \n [4] tools_4.2.3 backports_1.4.1 utf8_1.2.4 \n [7] R6_2.5.1 DBI_1.1.3 colorspace_2.1-0 \n[10] withr_2.5.2 tidyselect_1.2.0 curl_5.2.0 \n[13] compiler_4.2.3 textshaping_0.3.7 cli_3.6.2 \n[16] rvest_1.0.3 expm_0.999-8 flextable_0.9.4 \n[19] xml2_1.3.6 officer_0.6.3 fontBitstreamVera_0.1.1\n[22] labeling_0.4.3 mvtnorm_1.2-4 askpass_1.2.0 \n[25] systemfonts_1.0.5 stringr_1.5.1 digest_0.6.33 \n[28] rmarkdown_2.25 svglite_2.1.3 gfonts_0.2.0 \n[31] pkgconfig_2.0.3 htmltools_0.5.7 highr_0.10 \n[34] fastmap_1.1.1 htmlwidgets_1.6.4 rlang_1.1.2 \n[37] rstudioapi_0.15.0 httpcode_0.3.0 shiny_1.8.0 \n[40] farver_2.1.1 generics_0.1.3 jsonlite_1.8.8 \n[43] car_3.1-2 zip_2.3.0 magrittr_2.0.3 \n[46] Formula_1.2-5 Rcpp_1.0.11 munsell_0.5.0 \n[49] fansi_1.0.6 abind_1.4-5 gdtools_0.3.5 \n[52] lifecycle_1.0.4 chk_0.9.1 stringi_1.8.3 \n[55] yaml_2.3.8 carData_3.0-5 promises_1.2.1 \n[58] crayon_1.5.2 lattice_0.20-45 splines_4.2.3 \n[61] pander_0.6.5 pillar_1.9.0 igraph_1.6.0 \n[64] uuid_1.1-1 codetools_0.2-19 crul_1.4.0 \n[67] glue_1.6.2 evaluate_0.23 msm_1.7.1 \n[70] mitools_2.4 fontLiberation_0.1.0 data.table_1.14.10 \n[73] vctrs_0.6.5 httpuv_1.6.13 gtable_0.3.4 \n[76] openssl_2.1.1 purrr_1.0.2 tidyr_1.3.0 \n[79] assertthat_0.2.1 xfun_0.41 mime_0.12 \n[82] later_1.3.2 ragg_1.2.7 viridisLite_0.4.2 \n[85] tibble_3.2.1 ellipsis_0.3.2 rlemon_0.2.1" + "text": "Version info\nThis chapter was rendered using the following version of R and its packages:\n\n\nR version 4.2.3 (2023-03-15)\nPlatform: x86_64-pc-linux-gnu (64-bit)\nRunning under: Ubuntu 22.04.3 LTS\n\nMatrix products: default\nBLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3\nLAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so\n\nlocale:\n [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8 \n [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8 \n [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C \n[10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C \n\nattached base packages:\n[1] grid stats graphics grDevices utils datasets methods \n[8] base \n\nother attached packages:\n [1] interactions_1.1.5 survey_4.2-1 survival_3.5-3 Matrix_1.6-4 \n [5] interactionR_0.1.7 simcausal_0.5.6 scales_1.3.0 ggplot2_3.4.4 \n [9] xtable_1.8-4 dplyr_1.1.4 kableExtra_1.3.4 knitr_1.45 \n[13] cowplot_1.1.2 broom_1.0.5 MatchIt_4.5.5 jtools_2.2.2 \n[17] sandwich_3.1-0 lmtest_0.9-40 zoo_1.8-12 optmatch_0.10.7 \n[21] WeightIt_0.14.2 cobalt_4.5.2 table1_1.4.3 \n\nloaded via a namespace (and not attached):\n [1] fontquiver_0.2.1 webshot_0.5.5 httr_1.4.7 \n [4] tools_4.2.3 backports_1.4.1 utf8_1.2.4 \n [7] R6_2.5.1 DBI_1.1.3 colorspace_2.1-0 \n[10] withr_2.5.2 tidyselect_1.2.0 curl_5.2.0 \n[13] compiler_4.2.3 textshaping_0.3.7 cli_3.6.2 \n[16] rvest_1.0.3 expm_0.999-8 flextable_0.9.4 \n[19] xml2_1.3.6 officer_0.6.3 fontBitstreamVera_0.1.1\n[22] labeling_0.4.3 mvtnorm_1.2-4 askpass_1.2.0 \n[25] systemfonts_1.0.5 stringr_1.5.1 digest_0.6.33 \n[28] rmarkdown_2.25 svglite_2.1.3 gfonts_0.2.0 \n[31] pkgconfig_2.0.3 htmltools_0.5.7 highr_0.10 \n[34] fastmap_1.1.1 htmlwidgets_1.6.4 rlang_1.1.2 \n[37] rstudioapi_0.15.0 httpcode_0.3.0 shiny_1.8.0 \n[40] farver_2.1.1 generics_0.1.3 jsonlite_1.8.8 \n[43] car_3.1-2 zip_2.3.0 magrittr_2.0.3 \n[46] Formula_1.2-5 Rcpp_1.0.11 munsell_0.5.0 \n[49] fansi_1.0.6 abind_1.4-5 gdtools_0.3.5 \n[52] lifecycle_1.0.4 chk_0.9.1 stringi_1.8.3 \n[55] yaml_2.3.8 carData_3.0-5 promises_1.2.1 \n[58] crayon_1.5.2 lattice_0.20-45 splines_4.2.3 \n[61] pander_0.6.5 pillar_1.9.0 uuid_1.1-1 \n[64] igraph_1.6.0 codetools_0.2-19 crul_1.4.0 \n[67] glue_1.6.2 evaluate_0.23 msm_1.7.1 \n[70] mitools_2.4 fontLiberation_0.1.0 data.table_1.14.10 \n[73] vctrs_0.6.5 httpuv_1.6.13 gtable_0.3.4 \n[76] openssl_2.1.1 purrr_1.0.2 tidyr_1.3.0 \n[79] assertthat_0.2.1 xfun_0.41 mime_0.12 \n[82] later_1.3.2 ragg_1.2.7 viridisLite_0.4.2 \n[85] tibble_3.2.1 ellipsis_0.3.2 rlemon_0.2.1" }, { "objectID": "chapter_07.html#references", @@ -228,7 +228,7 @@ "href": "chapter_10.html#network-meta-analysis-of-clinical-trials", "title": "6  Systematic review and meta-analysis of Real-World Evidence", "section": "6.3 Network meta-analysis of clinical trials", - "text": "6.3 Network meta-analysis of clinical trials\nWe here use the R packages netmeta for conducting a frequentist network meta-analysis. A detailed tutorial on the use of netmeta is available from the book Doing Meta-Analysis with R: A Hands-On Guide.\n\n6.3.1 Interventions for coronavirus disease 2019\nWe here consider data from a study which aimed to assess the comparative effectiveness of remdesivir and tocilizumab for reducing mortality in hospitalised COVID-19 patients. 80 trials were identified from two published network meta-analyses (Selvarajan et al. 2022), (Siemieniuk et al. 2020), a living COVID-19 trial database (COVID-NMA Initiative) [Covid-NMA.com], and a clinical trial database [clinicaltrials.gov]. Trials were included in this study if the patient population included hospitalized COVID-19 patients, active treatment was remdesivir or tocilizumab, comparator treatment was placebo or standard care, short-term mortality data was available, and the trial was published. 21 trials were included. For included trials, a risk of bias score was extracted from the COVID-NMA Initiative.\n\n\n\n\n\nstudlab\ntreat1\ntreat2\nevent1\nn1\nevent2\nn2\n\n\n\n\nAder\nREM\nSTD\n34\n414\n37\n418\n\n\nBeigel (ACTT-1)\nREM\nSTD\n59\n541\n77\n521\n\n\nBroman\nTOCI\nSTD\n1\n57\n0\n29\n\n\nCriner\nREM\nSTD\n4\n384\n4\n200\n\n\nDeclerq (COV-AID)\nTOCI\nSTD\n10\n81\n9\n74\n\n\nGordon (REMAP-CAP)\nTOCI\nSTD\n83\n353\n116\n358\n\n\nHermine (CORIMUNO)\nTOCI\nSTD\n7\n63\n8\n67\n\n\nHorby (RECOVERY)\nTOCI\nSTD\n621\n2022\n729\n2094\n\n\nIslam\nREM\nSTD\n0\n30\n0\n30\n\n\nMahajan\nREM\nSTD\n5\n34\n3\n36\n\n\nPan (WHO Solidarity)\nREM\nSTD\n602\n4146\n643\n4129\n\n\nRosas (COVACTA)\nTOCI\nSTD\n58\n294\n28\n144\n\n\nRutgers\nTOCI\nSTD\n21\n174\n34\n180\n\n\nSalama (EMPACTA)\nTOCI\nSTD\n26\n249\n11\n128\n\n\nSalvarani\nTOCI\nSTD\n2\n60\n1\n63\n\n\nSoin (COVINTOC)\nTOCI\nSTD\n11\n92\n15\n88\n\n\nSpinner\nREM\nSTD\n5\n384\n4\n200\n\n\nStone (BACC-BAY)\nTOCI\nSTD\n9\n161\n4\n82\n\n\nTalaschian\nTOCI\nSTD\n5\n17\n4\n19\n\n\nVeiga (TOCIBRAS)\nTOCI\nSTD\n14\n65\n6\n64\n\n\nWang\nREM\nSTD\n22\n158\n10\n78\n\n\n\n\n\n\n\nThe corresponding network is displayed below:\n\n\n\n\n\nEvidence network of the 21 coronavirus-19 trials\n\n\n\n\nWe use the following command to calculate the log odds ratios and corresponding standard errors for each study:\n\ncovid <- pairwise(treat = treat, \n event = event, \n n = n, \n studlab = studlab, \n sm = \"OR\")\nhead(covid)\n\n\n\n\n\n\nTE\nseTE\nstudlab\ntreat1\ntreat2\nevent1\nn1\nevent2\nn2\nincr\nallstudies\n\n\n\n\n-0.0819293\n0.2483849\nAder\nREM\nSTD\n34\n414\n37\n418\n0.0\nFALSE\n\n\n-0.3483875\n0.1851030\nBeigel (ACTT-1)\nREM\nSTD\n59\n541\n77\n521\n0.0\nFALSE\n\n\n0.4487619\n1.6487159\nBroman\nTOCI\nSTD\n1\n57\n0\n29\n0.5\nFALSE\n\n\n-0.6620566\n0.7125543\nCriner\nREM\nSTD\n4\n384\n4\n200\n0.0\nFALSE\n\n\n0.0170679\n0.4904898\nDeclerq (COV-AID)\nTOCI\nSTD\n10\n81\n9\n74\n0.0\nFALSE\n\n\n-0.4442338\n0.1688337\nGordon (REMAP-CAP)\nTOCI\nSTD\n83\n353\n116\n358\n0.0\nFALSE\n\n\n\n\n\n\n\nBelow, we conduct a random effects network meta-analysis where we consider standard care (STD) as the control treatment. Note that we have one study where zero cell counts occur, this study will not contribute to the NMA as the log odds ratio and its standard error cannot be determined.\n\nNMA.covid <- netmeta(TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2,\n studlab = studlab, data = covid, sm = \"OR\", ref = \"STD\",\n comb.random = TRUE, common = FALSE, warn = FALSE)\nNMA.covid \n\nNumber of studies: k = 20\nNumber of pairwise comparisons: m = 20\nNumber of treatments: n = 3\nNumber of designs: d = 2\n\nRandom effects model\n\nTreatment estimate (sm = 'OR', comparison: other treatments vs 'STD'):\n OR 95%-CI z p-value\nREM 0.8999 [0.8067; 1.0039] -1.89 0.0588\nSTD . . . .\nTOCI 0.8301 [0.7434; 0.9268] -3.31 0.0009\n\nQuantifying heterogeneity / inconsistency:\ntau^2 = 0; tau = 0; I^2 = 0% [0.0%; 48.9%]\n\nTests of heterogeneity (within designs) and inconsistency (between designs):\n Q d.f. p-value\nTotal 16.38 18 0.5663\nWithin designs 16.38 18 0.5663\nBetween designs 0.00 0 --\n\n\nA league table of the treatment effect estimates is given below:\n\nnetleague(NMA.covid)\n\nLeague table (random effects model):\n \n REM 0.8999 [0.8067; 1.0039] .\n 0.8999 [0.8067; 1.0039] STD 1.2047 [1.0789; 1.3451]\n 1.0842 [0.9282; 1.2663] 1.2047 [1.0789; 1.3451] TOCI\n\n\nWe can also present the results in a forest plot:\n\n\n\n\n\nWe now consider a Bayesian random effects network meta-analysis that analyzes the observed event counts using a binomial link function.\n\nbdata <- data.frame(study = studlab,\n treatment = treat,\n responders = event,\n sampleSize = n)\n\nnetwork <- mtc.network(data.ab = bdata)\n\nmodel <- mtc.model(network,\n likelihood = \"binom\",\n link = \"log\",\n linearModel = \"random\",\n n.chain = 3)\n\n\n# Adaptation\nmcmc1 <- mtc.run(model, n.adapt = 1000, n.iter = 1000, thin = 10)\n\nCompiling model graph\n Resolving undeclared variables\n Allocating nodes\nGraph information:\n Observed stochastic nodes: 42\n Unobserved stochastic nodes: 45\n Total graph size: 930\n\nInitializing model\n\n# Sampling\nmcmc2 <- mtc.run(model, n.adapt = 10000, n.iter = 100000, thin = 10)\n\nCompiling model graph\n Resolving undeclared variables\n Allocating nodes\nGraph information:\n Observed stochastic nodes: 42\n Unobserved stochastic nodes: 45\n Total graph size: 930\n\nInitializing model\n\n\nWe can extract the pooled treatment effect estimates from the posterior distribution. When using STD as control group, we have:\n\nsummary(relative.effect(mcmc2, t1 = \"STD\"))\n\n\nResults on the Log Risk Ratio scale\n\nIterations = 10010:110000\nThinning interval = 10 \nNumber of chains = 3 \nSample size per chain = 10000 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\nd.STD.REM -0.1076 0.09757 0.0005633 0.0008000\nd.STD.TOCI -0.1122 0.08214 0.0004742 0.0008098\nsd.d 0.1126 0.08766 0.0005061 0.0017579\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\nd.STD.REM -0.316478 -0.16022 -0.10427 -0.05156 0.08405\nd.STD.TOCI -0.258217 -0.16295 -0.11960 -0.06962 0.07662\nsd.d 0.004789 0.04533 0.09483 0.15828 0.32754\n\n\nThe corresponding odds ratios are as follows:\n\n\n\n\n\nComparison\n95% CrI\n\n\n\n\nREM vs. STD\n0.9 (0.73; 1.09)\n\n\nTOCI vs. STD\n0.89 (0.77; 1.08)\n\n\nREM vs. TOCI\n1.02 (0.75; 1.26)\n\n\n\n\n\n\n\nFinally, we expand the COVID-19 network with trials investigating the effectiveness of hydroxychloroquine (HCQ), lopinavir/ritonavir (LOPI), dexamethasone (DEXA) or interferon-\\(\\beta\\) (INTB) (Selvarajan et al. 2022). The corresponding network is displayed below:\n\n\n\n\n\nEvidence network of the 33 coronavirus-19 trials\n\n\n\n\nWe conducted a random effects network meta-analysis, results are depicted below:\n\n\nNumber of studies: k = 33\nNumber of pairwise comparisons: m = 33\nNumber of treatments: n = 7\nNumber of designs: d = 6\n\nRandom effects model\n\nTreatment estimate (sm = 'OR', comparison: other treatments vs 'STD'):\n OR 95%-CI z p-value 95%-PI\nDEXA 0.8557 [0.7558; 0.9688] -2.46 0.0139 [0.7463; 0.9812]\nHCQ 1.1809 [0.8934; 1.5610] 1.17 0.2428 [0.8786; 1.5872]\nINTB 1.1606 [0.9732; 1.3841] 1.66 0.0973 [0.9604; 1.4026]\nLOPI 1.0072 [0.8906; 1.1392] 0.11 0.9085 [0.8794; 1.1537]\nREM 0.8983 [0.8014; 1.0070] -1.84 0.0658 [0.7913; 1.0199]\nSTD . . . . .\nTOCI 0.8304 [0.7410; 0.9306] -3.20 0.0014 [0.7316; 0.9426]\n\nQuantifying heterogeneity / inconsistency:\ntau^2 = 0.0004; tau = 0.0205; I^2 = 0.6% [0.0%; 42.3%]\n\nTests of heterogeneity (within designs) and inconsistency (between designs):\n Q d.f. p-value\nTotal 27.18 27 0.4543\nWithin designs 27.18 27 0.4543\nBetween designs 0.00 0 --\n\n\nWe can calculate the P score for each treatment as follows:\n\nnetrank(NMA.covidf)\n\n P-score\nTOCI 0.9070\nDEXA 0.8357\nREM 0.7143\nSTD 0.4027\nLOPI 0.3899\nHCQ 0.1336\nINTB 0.1166\n\n\n\n\n6.3.2 Pharmacologic treatments for chronic obstructive pulmonary disease\nIn this example, we consider the resuls from a systematic review of randomized controlled trials on pharmacologic treatments for chronic obstructive pulmonary disease (Baker, Baker, and Coleman 2009). The primary outcome, occurrence of one or more episodes of COPD exacerbation, is binary (yes / no). For this outcome, five drug treatments (fluticasone, budesonide, salmeterol, formoterol, tiotropium) and two combinations (fluticasone + salmeterol, budesonide + formoterol) were compared to placebo. The authors considered the two combinations as separate treatments instead of evaluating the individual components.\n\ndata(Baker2009)\n\n\n\n\n\n\nstudy\nyear\nid\ntreatment\nexac\ntotal\n\n\n\n\nLlewellyn-Jones 1996\n1996\n1\nFluticasone\n0\n8\n\n\nLlewellyn-Jones 1996\n1996\n1\nPlacebo\n3\n8\n\n\nBoyd 1997\n1997\n2\nSalmeterol\n47\n229\n\n\nBoyd 1997\n1997\n2\nPlacebo\n59\n227\n\n\nPaggiaro 1998\n1998\n3\nFluticasone\n45\n142\n\n\nPaggiaro 1998\n1998\n3\nPlacebo\n51\n139\n\n\n\n\n\n\n\n\nBaker <- pairwise(treat = treatment,\n event = exac,\n n = total,\n studlab = id,\n sm = \"OR\",\n data = Baker2009)\n\nNMA.COPD <- netmeta(TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2,\n studlab = studlab, data = Baker, sm = \"OR\", ref = \"Placebo\",\n comb.random = TRUE)\n\nWarning: Comparisons with missing TE / seTE or zero seTE not considered in\nnetwork meta-analysis.\n\n\nComparisons not considered in network meta-analysis:\n studlab treat1 treat2 TE seTE\n 39 Fluticasone+Salmeterol Placebo NA NA\n 39 Fluticasone+Salmeterol Salmeterol NA NA\n 39 Salmeterol Placebo NA NA\n\nnetgraph(NMA.COPD)\n\n\n\n\n\n\n6.3.3 Advanced Therapies for Ulcerative Colitis\nIn this example, we consider a systematic literature review of Phase 3 randomized controlled trials investigating the following advanced therapies: infliximab, adalimumab, vedolizumab, golimumab, tofacitinib, ustekinumab, filgotinib, ozanimod, and upadacitinib (Panaccione et al. 2023). This review included 48 RCTs, from which 23 were found eligible for inclusion in a network meta-analysis. The included RCT populations were largely comparable in their baseline characteristics, though some heterogeneity was noted in weight, disease duration, extent of disease, and concomitant medications. A risk of bias assessment showed a low risk of bias for all included RCTs, which were all industry sponsored.\nWe here focus on the synthesis of 18 trials that contributed efficacy data for induction in bio-naive populations. The following FDA- and/or EMA-approved biologic or SMD doses were investigated:\n\nAdalimumab subcutaneous 160 mg at week 0, 80 mg at week 2, and 40 mg at week 4 (ADA160/80)\nInfliximab intravenous 5 mg/kg (INF5) at weeks 0, 2, and 6 then every 8 weeks\nInfliximab intravenous 10 mg/kg (INF10) at weeks 0, 2, and 6 then every 8 weeks\nFilgotinib oral 100 mg once daily (FIL100)\nFilgotinib oral 200 mg once daily (FIL200)\nGolimumab subcutaneous 200 mg at week 0 and 100 mg at week 2 (GOL200/100)\nOzanimod oral 0.23 mg once daily for 4 days, 0.46 mg once daily for 3 days, then 0.92 mg once daily (OZA0.92)\nTofacitinib oral 10 mg twice daily for 8 weeks (TOF10)\nUpadacitinib oral 45 mg once daily for 8 weeks (UPA45)\nUstekinumab intravenous 6 mg/kg at week 0 (UST6)\nVedolizumab intravenous 300 mg at weeks 0, 2, and 6 (VED300)\n\nThe reference treatment is placebo (PBO).\n\n\n\nEfficacy outcomes (i.e., clinical remission) data of induction bio-naïve populations \n\n\nstudlab\ntreat1\ntreat2\nevent1\nn1\nevent2\nn2\n\n\n\n\nACT-1\nINF10\nINF5\n39\n122\n47\n121\n\n\nACT-1\nINF10\nPBO\n39\n122\n18\n121\n\n\nACT-1\nINF5\nPBO\n47\n121\n18\n121\n\n\nACT-2\nINF10\nINF5\n33\n120\n41\n121\n\n\nACT-2\nINF10\nPBO\n33\n120\n7\n123\n\n\nACT-2\nINF5\nPBO\n41\n121\n7\n123\n\n\nGEMINI 1\nVED300\nPBO\n30\n130\n5\n76\n\n\nJapic CTI-060298\nINF5\nPBO\n21\n104\n11\n104\n\n\nJiang 2015\nINF5\nPBO\n22\n41\n9\n41\n\n\nM10-447\nADA160/80\nPBO\n9\n90\n11\n96\n\n\nNCT01551290\nINF5\nPBO\n11\n50\n5\n49\n\n\nNCT02039505\nVED300\nPBO\n22\n79\n6\n41\n\n\nOCTAVE 1\nTOF10\nPBO\n56\n222\n9\n57\n\n\nOCTAVE 2\nTOF10\nPBO\n43\n195\n4\n47\n\n\nPURSUIT-SC\nGOL200/100\nPBO\n45\n253\n16\n251\n\n\nSELECTION\nFIL100\nFIL200\n47\n277\n60\n245\n\n\nSELECTION\nFIL100\nPBO\n47\n277\n17\n137\n\n\nSELECTION\nFIL200\nPBO\n60\n245\n17\n137\n\n\nTRUE NORTH\nOZA0.92\nPBO\n66\n299\n10\n151\n\n\nU-ACCOMPLISH\nUPA45\nPBO\n54\n166\n3\n81\n\n\nU-ACHIEVE Study 2\nUPA45\nPBO\n41\n145\n4\n72\n\n\nULTRA-1\nADA160/80\nPBO\n24\n130\n12\n130\n\n\nULTRA-2\nADA160/80\nPBO\n32\n150\n16\n145\n\n\nUNIFI\nUST6\nPBO\n27\n147\n15\n151\n\n\n\n\n\n\n\nThe corresponding network is displayed below:\n\n\n\n\n\nEvidence network of 18 trials that contributed efficacy data for induction in bio-naive populations\n\n\n\n\nBelow, we conduct a random effects network meta-analysis of the reported study effects (expressed as odds ratio) and consider placebo (treat = \"PBO\") as the control treatment.\n\nNMA.uc <- netmeta(TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2,\n studlab = studlab, data = UlcerativeColitis, sm = \"OR\", \n ref = \"PBO\", common = FALSE, comb.random = TRUE)\nNMA.uc\n\nAll treatments except FIL100 and UST6 are significantly more efficacious than PBO at inducing clinical remission. We can now estimate the probabilities of each treatment being at each possible rank and the SUCRAs (Surface Under the Cumulative RAnking curve):\n\nsucra.uc <- rankogram(NMA.uc, nsim = 100, random = TRUE, common = FALSE, \n small.values = \"undesirable\")\n\n# Exctract the SUCRA values\nsucra.uc$ranking.random\n\n ADA160/80 FIL100 FIL200 GOL200/100 INF10 INF5 OZA0.92 \n0.27545455 0.19454545 0.40545455 0.63909091 0.60181818 0.75363636 0.77818182 \n PBO TOF10 UPA45 UST6 VED300 \n0.01818182 0.39454545 0.98454545 0.34090909 0.61363636 \n\n\nThese results indicate that 98.5% of the evaluated treatments are worse than UPA45." + "text": "6.3 Network meta-analysis of clinical trials\nWe here use the R packages netmeta for conducting a frequentist network meta-analysis. A detailed tutorial on the use of netmeta is available from the book Doing Meta-Analysis with R: A Hands-On Guide.\n\n6.3.1 Interventions for coronavirus disease 2019\nWe here consider data from a study which aimed to assess the comparative effectiveness of remdesivir and tocilizumab for reducing mortality in hospitalised COVID-19 patients. 80 trials were identified from two published network meta-analyses (Selvarajan et al. 2022), (Siemieniuk et al. 2020), a living COVID-19 trial database (COVID-NMA Initiative) [Covid-NMA.com], and a clinical trial database [clinicaltrials.gov]. Trials were included in this study if the patient population included hospitalized COVID-19 patients, active treatment was remdesivir or tocilizumab, comparator treatment was placebo or standard care, short-term mortality data was available, and the trial was published. 21 trials were included. For included trials, a risk of bias score was extracted from the COVID-NMA Initiative.\n\n\n\n\n\nstudlab\ntreat1\ntreat2\nevent1\nn1\nevent2\nn2\n\n\n\n\nAder\nREM\nSTD\n34\n414\n37\n418\n\n\nBeigel (ACTT-1)\nREM\nSTD\n59\n541\n77\n521\n\n\nBroman\nTOCI\nSTD\n1\n57\n0\n29\n\n\nCriner\nREM\nSTD\n4\n384\n4\n200\n\n\nDeclerq (COV-AID)\nTOCI\nSTD\n10\n81\n9\n74\n\n\nGordon (REMAP-CAP)\nTOCI\nSTD\n83\n353\n116\n358\n\n\nHermine (CORIMUNO)\nTOCI\nSTD\n7\n63\n8\n67\n\n\nHorby (RECOVERY)\nTOCI\nSTD\n621\n2022\n729\n2094\n\n\nIslam\nREM\nSTD\n0\n30\n0\n30\n\n\nMahajan\nREM\nSTD\n5\n34\n3\n36\n\n\nPan (WHO Solidarity)\nREM\nSTD\n602\n4146\n643\n4129\n\n\nRosas (COVACTA)\nTOCI\nSTD\n58\n294\n28\n144\n\n\nRutgers\nTOCI\nSTD\n21\n174\n34\n180\n\n\nSalama (EMPACTA)\nTOCI\nSTD\n26\n249\n11\n128\n\n\nSalvarani\nTOCI\nSTD\n2\n60\n1\n63\n\n\nSoin (COVINTOC)\nTOCI\nSTD\n11\n92\n15\n88\n\n\nSpinner\nREM\nSTD\n5\n384\n4\n200\n\n\nStone (BACC-BAY)\nTOCI\nSTD\n9\n161\n4\n82\n\n\nTalaschian\nTOCI\nSTD\n5\n17\n4\n19\n\n\nVeiga (TOCIBRAS)\nTOCI\nSTD\n14\n65\n6\n64\n\n\nWang\nREM\nSTD\n22\n158\n10\n78\n\n\n\n\n\n\n\nThe corresponding network is displayed below:\n\n\n\n\n\nEvidence network of the 21 coronavirus-19 trials\n\n\n\n\nWe use the following command to calculate the log odds ratios and corresponding standard errors for each study:\n\ncovid <- pairwise(treat = treat, \n event = event, \n n = n, \n studlab = studlab, \n sm = \"OR\")\nhead(covid)\n\n\n\n\n\n\nTE\nseTE\nstudlab\ntreat1\ntreat2\nevent1\nn1\nevent2\nn2\nincr\nallstudies\n\n\n\n\n-0.0819293\n0.2483849\nAder\nREM\nSTD\n34\n414\n37\n418\n0.0\nFALSE\n\n\n-0.3483875\n0.1851030\nBeigel (ACTT-1)\nREM\nSTD\n59\n541\n77\n521\n0.0\nFALSE\n\n\n0.4487619\n1.6487159\nBroman\nTOCI\nSTD\n1\n57\n0\n29\n0.5\nFALSE\n\n\n-0.6620566\n0.7125543\nCriner\nREM\nSTD\n4\n384\n4\n200\n0.0\nFALSE\n\n\n0.0170679\n0.4904898\nDeclerq (COV-AID)\nTOCI\nSTD\n10\n81\n9\n74\n0.0\nFALSE\n\n\n-0.4442338\n0.1688337\nGordon (REMAP-CAP)\nTOCI\nSTD\n83\n353\n116\n358\n0.0\nFALSE\n\n\n\n\n\n\n\nBelow, we conduct a random effects network meta-analysis where we consider standard care (STD) as the control treatment. Note that we have one study where zero cell counts occur, this study will not contribute to the NMA as the log odds ratio and its standard error cannot be determined.\n\nNMA.covid <- netmeta(TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2,\n studlab = studlab, data = covid, sm = \"OR\", ref = \"STD\",\n comb.random = TRUE, common = FALSE, warn = FALSE)\nNMA.covid \n\nNumber of studies: k = 20\nNumber of pairwise comparisons: m = 20\nNumber of treatments: n = 3\nNumber of designs: d = 2\n\nRandom effects model\n\nTreatment estimate (sm = 'OR', comparison: other treatments vs 'STD'):\n OR 95%-CI z p-value\nREM 0.8999 [0.8067; 1.0039] -1.89 0.0588\nSTD . . . .\nTOCI 0.8301 [0.7434; 0.9268] -3.31 0.0009\n\nQuantifying heterogeneity / inconsistency:\ntau^2 = 0; tau = 0; I^2 = 0% [0.0%; 48.9%]\n\nTests of heterogeneity (within designs) and inconsistency (between designs):\n Q d.f. p-value\nTotal 16.38 18 0.5663\nWithin designs 16.38 18 0.5663\nBetween designs 0.00 0 --\n\n\nA league table of the treatment effect estimates is given below:\n\nnetleague(NMA.covid)\n\nLeague table (random effects model):\n \n REM 0.8999 [0.8067; 1.0039] .\n 0.8999 [0.8067; 1.0039] STD 1.2047 [1.0789; 1.3451]\n 1.0842 [0.9282; 1.2663] 1.2047 [1.0789; 1.3451] TOCI\n\n\nWe can also present the results in a forest plot:\n\n\n\n\n\nWe now consider a Bayesian random effects network meta-analysis that analyzes the observed event counts using a binomial link function.\n\nbdata <- data.frame(study = studlab,\n treatment = treat,\n responders = event,\n sampleSize = n)\n\nnetwork <- mtc.network(data.ab = bdata)\n\nmodel <- mtc.model(network,\n likelihood = \"binom\",\n link = \"log\",\n linearModel = \"random\",\n n.chain = 3)\n\n\n# Adaptation\nmcmc1 <- mtc.run(model, n.adapt = 1000, n.iter = 1000, thin = 10)\n\nCompiling model graph\n Resolving undeclared variables\n Allocating nodes\nGraph information:\n Observed stochastic nodes: 42\n Unobserved stochastic nodes: 45\n Total graph size: 930\n\nInitializing model\n\n# Sampling\nmcmc2 <- mtc.run(model, n.adapt = 10000, n.iter = 100000, thin = 10)\n\nCompiling model graph\n Resolving undeclared variables\n Allocating nodes\nGraph information:\n Observed stochastic nodes: 42\n Unobserved stochastic nodes: 45\n Total graph size: 930\n\nInitializing model\n\n\nWe can extract the pooled treatment effect estimates from the posterior distribution. When using STD as control group, we have:\n\nsummary(relative.effect(mcmc2, t1 = \"STD\"))\n\n\nResults on the Log Risk Ratio scale\n\nIterations = 10010:110000\nThinning interval = 10 \nNumber of chains = 3 \nSample size per chain = 10000 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\nd.STD.REM -0.1086 0.09739 0.0005623 0.0008007\nd.STD.TOCI -0.1122 0.08272 0.0004776 0.0008179\nsd.d 0.1128 0.08863 0.0005117 0.0016525\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\nd.STD.REM -0.317134 -0.16162 -0.10394 -0.05227 0.08146\nd.STD.TOCI -0.256467 -0.16358 -0.11974 -0.06952 0.08152\nsd.d 0.004703 0.04619 0.09335 0.15812 0.33068\n\n\nThe corresponding odds ratios are as follows:\n\n\n\n\n\nComparison\n95% CrI\n\n\n\n\nREM vs. STD\n0.9 (0.73; 1.08)\n\n\nTOCI vs. STD\n0.89 (0.77; 1.08)\n\n\nREM vs. TOCI\n1.01 (0.75; 1.26)\n\n\n\n\n\n\n\nFinally, we expand the COVID-19 network with trials investigating the effectiveness of hydroxychloroquine (HCQ), lopinavir/ritonavir (LOPI), dexamethasone (DEXA) or interferon-\\(\\beta\\) (INTB) (Selvarajan et al. 2022). The corresponding network is displayed below:\n\n\n\n\n\nEvidence network of the 33 coronavirus-19 trials\n\n\n\n\nWe conducted a random effects network meta-analysis, results are depicted below:\n\n\nNumber of studies: k = 33\nNumber of pairwise comparisons: m = 33\nNumber of treatments: n = 7\nNumber of designs: d = 6\n\nRandom effects model\n\nTreatment estimate (sm = 'OR', comparison: other treatments vs 'STD'):\n OR 95%-CI z p-value 95%-PI\nDEXA 0.8557 [0.7558; 0.9688] -2.46 0.0139 [0.7463; 0.9812]\nHCQ 1.1809 [0.8934; 1.5610] 1.17 0.2428 [0.8786; 1.5872]\nINTB 1.1606 [0.9732; 1.3841] 1.66 0.0973 [0.9604; 1.4026]\nLOPI 1.0072 [0.8906; 1.1392] 0.11 0.9085 [0.8794; 1.1537]\nREM 0.8983 [0.8014; 1.0070] -1.84 0.0658 [0.7913; 1.0199]\nSTD . . . . .\nTOCI 0.8304 [0.7410; 0.9306] -3.20 0.0014 [0.7316; 0.9426]\n\nQuantifying heterogeneity / inconsistency:\ntau^2 = 0.0004; tau = 0.0205; I^2 = 0.6% [0.0%; 42.3%]\n\nTests of heterogeneity (within designs) and inconsistency (between designs):\n Q d.f. p-value\nTotal 27.18 27 0.4543\nWithin designs 27.18 27 0.4543\nBetween designs 0.00 0 --\n\n\nWe can calculate the P score for each treatment as follows:\n\nnetrank(NMA.covidf)\n\n P-score\nTOCI 0.9070\nDEXA 0.8357\nREM 0.7143\nSTD 0.4027\nLOPI 0.3899\nHCQ 0.1336\nINTB 0.1166\n\n\n\n\n6.3.2 Pharmacologic treatments for chronic obstructive pulmonary disease\nIn this example, we consider the resuls from a systematic review of randomized controlled trials on pharmacologic treatments for chronic obstructive pulmonary disease (Baker, Baker, and Coleman 2009). The primary outcome, occurrence of one or more episodes of COPD exacerbation, is binary (yes / no). For this outcome, five drug treatments (fluticasone, budesonide, salmeterol, formoterol, tiotropium) and two combinations (fluticasone + salmeterol, budesonide + formoterol) were compared to placebo. The authors considered the two combinations as separate treatments instead of evaluating the individual components.\n\ndata(Baker2009)\n\n\n\n\n\n\nstudy\nyear\nid\ntreatment\nexac\ntotal\n\n\n\n\nLlewellyn-Jones 1996\n1996\n1\nFluticasone\n0\n8\n\n\nLlewellyn-Jones 1996\n1996\n1\nPlacebo\n3\n8\n\n\nBoyd 1997\n1997\n2\nSalmeterol\n47\n229\n\n\nBoyd 1997\n1997\n2\nPlacebo\n59\n227\n\n\nPaggiaro 1998\n1998\n3\nFluticasone\n45\n142\n\n\nPaggiaro 1998\n1998\n3\nPlacebo\n51\n139\n\n\n\n\n\n\n\n\nBaker <- pairwise(treat = treatment,\n event = exac,\n n = total,\n studlab = id,\n sm = \"OR\",\n data = Baker2009)\n\nNMA.COPD <- netmeta(TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2,\n studlab = studlab, data = Baker, sm = \"OR\", ref = \"Placebo\",\n comb.random = TRUE)\n\nWarning: Comparisons with missing TE / seTE or zero seTE not considered in\nnetwork meta-analysis.\n\n\nComparisons not considered in network meta-analysis:\n studlab treat1 treat2 TE seTE\n 39 Fluticasone+Salmeterol Placebo NA NA\n 39 Fluticasone+Salmeterol Salmeterol NA NA\n 39 Salmeterol Placebo NA NA\n\nnetgraph(NMA.COPD)\n\n\n\n\n\n\n6.3.3 Advanced Therapies for Ulcerative Colitis\nIn this example, we consider a systematic literature review of Phase 3 randomized controlled trials investigating the following advanced therapies: infliximab, adalimumab, vedolizumab, golimumab, tofacitinib, ustekinumab, filgotinib, ozanimod, and upadacitinib (Panaccione et al. 2023). This review included 48 RCTs, from which 23 were found eligible for inclusion in a network meta-analysis. The included RCT populations were largely comparable in their baseline characteristics, though some heterogeneity was noted in weight, disease duration, extent of disease, and concomitant medications. A risk of bias assessment showed a low risk of bias for all included RCTs, which were all industry sponsored.\nWe here focus on the synthesis of 18 trials that contributed efficacy data for induction in bio-naive populations. The following FDA- and/or EMA-approved biologic or SMD doses were investigated:\n\nAdalimumab subcutaneous 160 mg at week 0, 80 mg at week 2, and 40 mg at week 4 (ADA160/80)\nInfliximab intravenous 5 mg/kg (INF5) at weeks 0, 2, and 6 then every 8 weeks\nInfliximab intravenous 10 mg/kg (INF10) at weeks 0, 2, and 6 then every 8 weeks\nFilgotinib oral 100 mg once daily (FIL100)\nFilgotinib oral 200 mg once daily (FIL200)\nGolimumab subcutaneous 200 mg at week 0 and 100 mg at week 2 (GOL200/100)\nOzanimod oral 0.23 mg once daily for 4 days, 0.46 mg once daily for 3 days, then 0.92 mg once daily (OZA0.92)\nTofacitinib oral 10 mg twice daily for 8 weeks (TOF10)\nUpadacitinib oral 45 mg once daily for 8 weeks (UPA45)\nUstekinumab intravenous 6 mg/kg at week 0 (UST6)\nVedolizumab intravenous 300 mg at weeks 0, 2, and 6 (VED300)\n\nThe reference treatment is placebo (PBO).\n\n\n\nEfficacy outcomes (i.e., clinical remission) data of induction bio-naïve populations \n\n\nstudlab\ntreat1\ntreat2\nevent1\nn1\nevent2\nn2\n\n\n\n\nACT-1\nINF10\nINF5\n39\n122\n47\n121\n\n\nACT-1\nINF10\nPBO\n39\n122\n18\n121\n\n\nACT-1\nINF5\nPBO\n47\n121\n18\n121\n\n\nACT-2\nINF10\nINF5\n33\n120\n41\n121\n\n\nACT-2\nINF10\nPBO\n33\n120\n7\n123\n\n\nACT-2\nINF5\nPBO\n41\n121\n7\n123\n\n\nGEMINI 1\nVED300\nPBO\n30\n130\n5\n76\n\n\nJapic CTI-060298\nINF5\nPBO\n21\n104\n11\n104\n\n\nJiang 2015\nINF5\nPBO\n22\n41\n9\n41\n\n\nM10-447\nADA160/80\nPBO\n9\n90\n11\n96\n\n\nNCT01551290\nINF5\nPBO\n11\n50\n5\n49\n\n\nNCT02039505\nVED300\nPBO\n22\n79\n6\n41\n\n\nOCTAVE 1\nTOF10\nPBO\n56\n222\n9\n57\n\n\nOCTAVE 2\nTOF10\nPBO\n43\n195\n4\n47\n\n\nPURSUIT-SC\nGOL200/100\nPBO\n45\n253\n16\n251\n\n\nSELECTION\nFIL100\nFIL200\n47\n277\n60\n245\n\n\nSELECTION\nFIL100\nPBO\n47\n277\n17\n137\n\n\nSELECTION\nFIL200\nPBO\n60\n245\n17\n137\n\n\nTRUE NORTH\nOZA0.92\nPBO\n66\n299\n10\n151\n\n\nU-ACCOMPLISH\nUPA45\nPBO\n54\n166\n3\n81\n\n\nU-ACHIEVE Study 2\nUPA45\nPBO\n41\n145\n4\n72\n\n\nULTRA-1\nADA160/80\nPBO\n24\n130\n12\n130\n\n\nULTRA-2\nADA160/80\nPBO\n32\n150\n16\n145\n\n\nUNIFI\nUST6\nPBO\n27\n147\n15\n151\n\n\n\n\n\n\n\nThe corresponding network is displayed below:\n\n\n\n\n\nEvidence network of 18 trials that contributed efficacy data for induction in bio-naive populations\n\n\n\n\nBelow, we conduct a random effects network meta-analysis of the reported study effects (expressed as odds ratio) and consider placebo (treat = \"PBO\") as the control treatment.\n\nNMA.uc <- netmeta(TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2,\n studlab = studlab, data = UlcerativeColitis, sm = \"OR\", \n ref = \"PBO\", common = FALSE, comb.random = TRUE)\nNMA.uc\n\nAll treatments except FIL100 and UST6 are significantly more efficacious than PBO at inducing clinical remission. We can now estimate the probabilities of each treatment being at each possible rank and the SUCRAs (Surface Under the Cumulative RAnking curve):\n\nsucra.uc <- rankogram(NMA.uc, nsim = 100, random = TRUE, common = FALSE, \n small.values = \"undesirable\")\n\n# Exctract the SUCRA values\nsucra.uc$ranking.random\n\n ADA160/80 FIL100 FIL200 GOL200/100 INF10 INF5 OZA0.92 \n0.28363636 0.16818182 0.44000000 0.61818182 0.61636364 0.75909091 0.74909091 \n PBO TOF10 UPA45 UST6 VED300 \n0.01727273 0.42090909 0.97181818 0.35272727 0.60272727 \n\n\nThese results indicate that 97.2% of the evaluated treatments are worse than UPA45." }, { "objectID": "chapter_10.html#version-info", @@ -263,7 +263,7 @@ "href": "chapter_11.html#version-info", "title": "7  Individual Participant Data Meta-analysis of clinical trials and real-world data", "section": "Version info", - "text": "Version info\nThis chapter was rendered using the following version of R and its packages:\n\n\nR version 4.2.3 (2023-03-15)\nPlatform: x86_64-pc-linux-gnu (64-bit)\nRunning under: Ubuntu 22.04.3 LTS\n\nMatrix products: default\nBLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3\nLAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so\n\nlocale:\n [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8 \n [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8 \n [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C \n[10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C \n\nattached base packages:\n[1] stats graphics grDevices utils datasets methods base \n\nother attached packages:\n[1] meta_6.5-0 jarbes_2.0.0 dplyr_1.1.4 ggplot2_3.4.4 \n[5] table1_1.4.3 kableExtra_1.3.4\n\nloaded via a namespace (and not attached):\n [1] httr_1.4.7 tidyr_1.3.0 sfsmisc_1.1-16 \n [4] jsonlite_1.8.8 viridisLite_0.4.2 splines_4.2.3 \n [7] Formula_1.2-5 shiny_1.8.0 metafor_4.4-0 \n[10] yaml_2.3.8 numDeriv_2016.8-1.1 R2WinBUGS_2.1-22 \n[13] pillar_1.9.0 lattice_0.20-45 glue_1.6.2 \n[16] digest_0.6.33 promises_1.2.1 rvest_1.0.3 \n[19] minqa_1.2.6 colorspace_2.1-0 R2jags_0.7-1 \n[22] mcmcplots_0.4.3 htmltools_0.5.7 httpuv_1.6.13 \n[25] Matrix_1.6-4 pkgconfig_2.0.3 purrr_1.0.2 \n[28] xtable_1.8-4 scales_1.3.0 webshot_0.5.5 \n[31] svglite_2.1.3 rjags_4-15 later_1.3.2 \n[34] metadat_1.2-0 lme4_1.1-35.1 tibble_3.2.1 \n[37] farver_2.1.1 generics_0.1.3 ellipsis_0.3.2 \n[40] withr_2.5.2 cli_3.6.2 magrittr_2.0.3 \n[43] mime_0.12 evaluate_0.23 fansi_1.0.6 \n[46] nlme_3.1-162 MASS_7.3-58.2 xml2_1.3.6 \n[49] tools_4.2.3 lifecycle_1.0.4 stringr_1.5.1 \n[52] munsell_0.5.0 compiler_4.2.3 systemfonts_1.0.5 \n[55] rlang_1.1.2 nloptr_2.0.3 grid_4.2.3 \n[58] rstudioapi_0.15.0 CompQuadForm_1.4.3 htmlwidgets_1.6.4 \n[61] miniUI_0.1.1.1 labeling_0.4.3 rmarkdown_2.25 \n[64] boot_1.3-28.1 gtable_0.3.4 codetools_0.2-19 \n[67] abind_1.4-5 R6_2.5.1 gridExtra_2.3 \n[70] knitr_1.45 denstrip_1.5.4 fastmap_1.1.1 \n[73] utf8_1.2.4 mathjaxr_1.6-0 ggExtra_0.10.1 \n[76] stringi_1.8.3 parallel_4.2.3 Rcpp_1.0.11 \n[79] vctrs_0.6.5 tidyselect_1.2.0 xfun_0.41 \n[82] coda_0.19-4" + "text": "Version info\nThis chapter was rendered using the following version of R and its packages:\n\n\nR version 4.2.3 (2023-03-15)\nPlatform: x86_64-pc-linux-gnu (64-bit)\nRunning under: Ubuntu 22.04.3 LTS\n\nMatrix products: default\nBLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3\nLAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so\n\nlocale:\n [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8 \n [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8 \n [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C \n[10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C \n\nattached base packages:\n[1] stats graphics grDevices utils datasets methods base \n\nother attached packages:\n[1] meta_6.5-0 jarbes_2.0.0 dplyr_1.1.4 ggplot2_3.4.4 \n[5] table1_1.4.3 kableExtra_1.3.4\n\nloaded via a namespace (and not attached):\n [1] httr_1.4.7 tidyr_1.3.0 sfsmisc_1.1-16 \n [4] jsonlite_1.8.8 viridisLite_0.4.2 splines_4.2.3 \n [7] Formula_1.2-5 shiny_1.8.0 metafor_4.4-0 \n[10] yaml_2.3.8 numDeriv_2016.8-1.1 R2WinBUGS_2.1-22 \n[13] pillar_1.9.0 lattice_0.20-45 glue_1.6.2 \n[16] digest_0.6.33 RColorBrewer_1.1-3 promises_1.2.1 \n[19] minqa_1.2.6 rvest_1.0.3 colorspace_2.1-0 \n[22] R2jags_0.7-1 Matrix_1.6-4 mcmcplots_0.4.3 \n[25] htmltools_0.5.7 httpuv_1.6.13 plyr_1.8.9 \n[28] pkgconfig_2.0.3 purrr_1.0.2 xtable_1.8-4 \n[31] scales_1.3.0 webshot_0.5.5 svglite_2.1.3 \n[34] rjags_4-15 later_1.3.2 ggstats_0.5.1 \n[37] metadat_1.2-0 lme4_1.1-35.1 tibble_3.2.1 \n[40] farver_2.1.1 generics_0.1.3 ellipsis_0.3.2 \n[43] withr_2.5.2 cli_3.6.2 magrittr_2.0.3 \n[46] mime_0.12 evaluate_0.23 GGally_2.2.0 \n[49] fansi_1.0.6 nlme_3.1-162 MASS_7.3-58.2 \n[52] xml2_1.3.6 tools_4.2.3 lifecycle_1.0.4 \n[55] stringr_1.5.1 munsell_0.5.0 compiler_4.2.3 \n[58] systemfonts_1.0.5 rlang_1.1.2 nloptr_2.0.3 \n[61] grid_4.2.3 rstudioapi_0.15.0 CompQuadForm_1.4.3 \n[64] htmlwidgets_1.6.4 miniUI_0.1.1.1 labeling_0.4.3 \n[67] rmarkdown_2.25 boot_1.3-28.1 gtable_0.3.4 \n[70] codetools_0.2-19 abind_1.4-5 R6_2.5.1 \n[73] gridExtra_2.3 knitr_1.45 denstrip_1.5.4 \n[76] fastmap_1.1.1 utf8_1.2.4 mathjaxr_1.6-0 \n[79] ggExtra_0.10.1 stringi_1.8.3 parallel_4.2.3 \n[82] Rcpp_1.0.11 vctrs_0.6.5 tidyselect_1.2.0 \n[85] xfun_0.41 coda_0.19-4" }, { "objectID": "chapter_11.html#references", @@ -326,14 +326,14 @@ "href": "chapter_16.html#estimating-heterogeneous-treatment-effects-in-pairwise-meta-analysis", "title": "9  Prediction of individual treatment effect using data from multiple studies", "section": "9.1 Estimating heterogeneous treatment effects in pairwise meta-analysis", - "text": "9.1 Estimating heterogeneous treatment effects in pairwise meta-analysis\nWe hereby provide code for estimating patient-level treatment effects for the case when we have patient-level data from multiple randomized trials.\n\n9.1.1 Example of a continuous outcome\n\n9.1.1.1 Setup\nWe start by simulating an artificial dataset using the R package bipd:\n\nlibrary(bipd)\nds <- generate_ipdma_example(type = \"continuous\")\n\nLet us have a look at the dataset:\n\nhead(ds)\n\n studyid treat z1 z2 y\n1 1 0 -1.0250374 0.49359495 11\n2 1 0 1.3634580 -0.06700193 11\n3 1 1 -1.0207586 -0.41125330 8\n4 1 0 0.1811554 1.35029464 11\n5 1 0 0.7933182 -0.82219469 11\n6 1 1 -0.1877892 1.71953547 10\n\n\nThe simulated dataset contains information on the following variables:\n\nthe trial indicator studyid\nthe treatment indicator treat, which takes the values 0 for control and 1 for active treatment\ntwo prognostic variables z1 and z2\nthe continuous outcome y\n\n\n\n\n\n\n\nTable 9.1: The simulated dataset with a continuous outcome\n\n\n\n\n\n\n\n\n\n0\n(N=305)\n1\n(N=295)\nOverall\n(N=600)\n\n\n\n\nz1\n\n\n\n\n\nMean (SD)\n0.118 (1.06)\n0.0136 (1.07)\n0.0664 (1.07)\n\n\nMedian [Min, Max]\n0.0748 [-2.75, 3.05]\n-0.0745 [-3.21, 2.67]\n-0.00441 [-3.21, 3.05]\n\n\nz2\n\n\n\n\n\nMean (SD)\n0.0401 (1.05)\n-0.0362 (1.05)\n0.00259 (1.05)\n\n\nMedian [Min, Max]\n0.0341 [-3.17, 2.52]\n-0.106 [-2.84, 2.93]\n-0.00570 [-3.17, 2.93]\n\n\nstudyid\n\n\n\n\n\n1\n51 (16.7%)\n49 (16.6%)\n100 (16.7%)\n\n\n2\n46 (15.1%)\n54 (18.3%)\n100 (16.7%)\n\n\n3\n58 (19.0%)\n42 (14.2%)\n100 (16.7%)\n\n\n4\n52 (17.0%)\n48 (16.3%)\n100 (16.7%)\n\n\n5\n50 (16.4%)\n50 (16.9%)\n100 (16.7%)\n\n\n6\n48 (15.7%)\n52 (17.6%)\n100 (16.7%)\n\n\n\n\n\n\n\n\n\n\n9.1.1.2 Model fitting\nWe synthesize the evidence using a Bayesian random effects meta-analysis model. The model is given in Equation 16.7 of the book. First we need set up the data and create the model:\n\nipd <- with(ds, ipdma.model.onestage(y = y, study = studyid, treat = treat,\n X = cbind(z1, z2), \n response = \"normal\", \n shrinkage = \"none\"), \n type = \"random\")\n\nThe JAGS model can be accessed as follows:\n\nipd$model.JAGS\n\nfunction () \n{\n for (i in 1:Np) {\n y[i] ~ dnorm(mu[i], sigma)\n mu[i] <- alpha[studyid[i]] + inprod(beta[], X[i, ]) + \n (1 - equals(treat[i], 1)) * inprod(gamma[], X[i, \n ]) + d[studyid[i], treat[i]]\n }\n sigma ~ dgamma(0.001, 0.001)\n for (j in 1:Nstudies) {\n d[j, 1] <- 0\n d[j, 2] ~ dnorm(delta[2], tau)\n }\n sd ~ dnorm(0, 1)\n T(0, )\n tau <- pow(sd, -2)\n delta[1] <- 0\n delta[2] ~ dnorm(0, 0.001)\n for (j in 1:Nstudies) {\n alpha[j] ~ dnorm(0, 0.001)\n }\n for (k in 1:Ncovariate) {\n beta[k] ~ dnorm(0, 0.001)\n }\n for (k in 1:Ncovariate) {\n gamma[k] ~ dnorm(0, 0.001)\n }\n}\n<environment: 0x55f3d7563230>\n\n\nWe can fit the treatment effect model as follows:\n\nsamples <- ipd.run(ipd, n.chains = 2, n.iter = 20,\n pars.save = c(\"alpha\", \"beta\", \"delta\", \"sd\", \"gamma\"))\ntrtbenefit <- round(treatment.effect(ipd, samples, newpatient = c(z1 = 1, z2 = 0.5)), 2)\n\nHere are the estimated model parameters:\n\nsummary(samples)\n\n\nIterations = 2001:2020\nThinning interval = 1 \nNumber of chains = 2 \nSample size per chain = 20 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\nalpha[1] 10.9960 0.05395 0.008531 0.008659\nalpha[2] 8.0128 0.06688 0.010574 0.027179\nalpha[3] 10.4861 0.06265 0.009906 0.019822\nalpha[4] 9.6116 0.05038 0.007966 0.005723\nalpha[5] 12.9818 0.06611 0.010453 0.024653\nalpha[6] 15.7881 0.04879 0.007714 0.014535\nbeta[1] 0.2074 0.02240 0.003541 0.006507\nbeta[2] 0.3182 0.02080 0.003289 0.002725\ndelta[1] 0.0000 0.00000 0.000000 0.000000\ndelta[2] -2.8673 0.33747 0.053358 0.044544\ngamma[1] -0.5104 0.03078 0.004867 0.008095\ngamma[2] 0.6115 0.02872 0.004540 0.005747\nsd 1.2001 0.29377 0.046449 0.074224\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\nalpha[1] 10.9094 10.9647 10.9963 11.0314 11.0917\nalpha[2] 7.8449 7.9806 8.0190 8.0527 8.1253\nalpha[3] 10.3921 10.4448 10.4757 10.5228 10.6150\nalpha[4] 9.5296 9.5771 9.6120 9.6366 9.7109\nalpha[5] 12.8548 12.9223 12.9905 13.0374 13.0757\nalpha[6] 15.7023 15.7617 15.7954 15.8139 15.8952\nbeta[1] 0.1693 0.1956 0.2077 0.2188 0.2519\nbeta[2] 0.2801 0.3045 0.3195 0.3319 0.3509\ndelta[1] 0.0000 0.0000 0.0000 0.0000 0.0000\ndelta[2] -3.5471 -3.0718 -2.8557 -2.5993 -2.3507\ngamma[1] -0.5667 -0.5288 -0.5201 -0.4838 -0.4601\ngamma[2] 0.5615 0.5900 0.6106 0.6335 0.6549\nsd 0.7871 0.9995 1.1971 1.3740 1.8053\n\n\n\n\n9.1.1.3 Prection\nWe can now predict the individualized treatment effect for a new patient with covariate values z1 = 1 and z2 = 0.5.\n\nround(treatment.effect(ipd, samples, newpatient = c(z1 = 1, z2 = 0.5)), 2)\n\n0.025 0.5 0.975 \n-3.70 -3.00 -2.48 \n\n\nThis means that the predicted outcome for patient with covariate values z1 = 1 and z2 = 0.5 will differ by -3 units when receiving the active treatment (treat = 1) as compared to the control treatment (treat = 0).\nWe can also predict treatment benefit for all patients in the sample, and look at the distribution of predicted benefit.\n\nlibrary(dplyr)\nlibrary(ggplot2)\n\nds <- ds %>% mutate(benefit = NA,\n study = paste(\"Trial\", studyid)) \n\nfor (i in seq(nrow(ds))) {\n newpat <- as.matrix(ds[i, c(\"z1\", \"z2\")])\n ds$benefit[i] <- treatment.effect(ipd, samples, newpatient = newpat)[\"0.5\"]\n}\n\nsummbenefit <- ds %>% group_by(study) %>% \n summarize(mediabenefit = median(benefit), meanbenefit = mean(benefit))\n\nggplot(ds, aes(x = benefit)) + \n geom_histogram(aes(y = after_stat(density)), alpha = 0.3) + \n geom_density() +\n geom_vline(data = summbenefit, aes(xintercept = meanbenefit), \n linewidth = 0.5, lty = 2) + \n facet_wrap(~study) + \n ylab(\"Density\") +\n xlab(\"Predicted treatment benefit\") + theme_bw()\n\n\n\n\nFigure 9.1: Distribution of predicted treatment benefit in each trial. Dashed lines represent the trial mean.\n\n\n\n\n\n\n9.1.1.4 Penalization\nLet us repeat the analysis, but this time while penalizing the treatment-covariate coefficients using a Bayesian LASSO prior.\n\nipd <- with(ds, ipdma.model.onestage(y = y, study = studyid, \n treat = treat,\n X = cbind(z1, z2), \n response = \"normal\", \n shrinkage = \"laplace\"), \n type = \"random\")\n\nsamples <- ipd.run(ipd, n.chains = 2, n.iter = 20, \n pars.save = c(\"alpha\", \"beta\", \"delta\", \"sd\", \"gamma\"))\n\nCompiling model graph\n Resolving undeclared variables\n Allocating nodes\nGraph information:\n Observed stochastic nodes: 600\n Unobserved stochastic nodes: 20\n Total graph size: 6039\n\nInitializing model\n\nround(treatment.effect(ipd, samples, newpatient = c(1,0.5)), 2)\n\n0.025 0.5 0.975 \n-3.94 -2.95 -1.79 \n\n\n\n\n\n9.1.2 Example of a binary outcome\n\n9.1.2.1 Setup\nWe now present the case of a binary outcome. We first generate a dataset as before, using the bipd package.\n\nds2 <- generate_ipdma_example(type = \"binary\")\nhead(ds2)\n\n studyid treat w1 w2 y\n1 1 1 0.3085440 0.1575700 1\n2 1 0 0.4926325 -0.4840050 0\n3 1 1 2.5380713 -0.6867120 0\n4 1 1 1.5699597 1.5699588 1\n5 1 0 -1.1898302 1.0758754 0\n6 1 0 -0.9250433 -0.2722173 1\n\n\nThe simulated dataset contains information on the following variables:\n\nthe trial indicator studyid\nthe treatment indicator treat, which takes the values 0 for control and 1 for active treatment\ntwo prognostic variables w1 and w2\nthe binary outcome y\n\n\n\n\n\n\n\nTable 9.2: The simulated dataset with a binary outcome\n\n\n\n\n\n\n\n\n\n0\n(N=322)\n1\n(N=278)\nOverall\n(N=600)\n\n\n\n\nw1\n\n\n\n\n\nMean (SD)\n-0.0283 (0.965)\n0.0915 (1.02)\n0.0272 (0.994)\n\n\nMedian [Min, Max]\n-0.0475 [-2.69, 2.49]\n0.123 [-2.71, 2.54]\n0.0111 [-2.71, 2.54]\n\n\nw2\n\n\n\n\n\nMean (SD)\n0.0447 (0.985)\n0.00111 (0.975)\n0.0245 (0.980)\n\n\nMedian [Min, Max]\n0.0640 [-2.30, 3.02]\n0.0276 [-3.04, 2.13]\n0.0317 [-3.04, 3.02]\n\n\nstudyid\n\n\n\n\n\n1\n54 (16.8%)\n46 (16.5%)\n100 (16.7%)\n\n\n2\n57 (17.7%)\n43 (15.5%)\n100 (16.7%)\n\n\n3\n54 (16.8%)\n46 (16.5%)\n100 (16.7%)\n\n\n4\n49 (15.2%)\n51 (18.3%)\n100 (16.7%)\n\n\n5\n51 (15.8%)\n49 (17.6%)\n100 (16.7%)\n\n\n6\n57 (17.7%)\n43 (15.5%)\n100 (16.7%)\n\n\n\n\n\n\n\n\n\n\n9.1.2.2 Model fitting\nWe use a Bayesian random effects model with binomial likelihood. This is similar to the model 16.7 of the book, but with a Binomial likelihood, i.e. \n\\[\ny_{ij}\\sim \\text{Binomial}(\\pi_{ij}) \\\\\n\\] \\[\n\\text{logit}(\\pi_{ij})=a_j+\\delta_j t_{ij}+ \\sum_{l=1}^{L}\\beta_l x_{ij}+ \\sum_{l=1}^{L}\\gamma_l x_{ij} t_{ij}\n\\] The remaining of the model is as in the book. We can penalize the estimated parameters for effect modification (\\(\\gamma\\)’s), using a Bayesian LASSO. We can do this using again the bipd package:\n\nipd2 <- with(ds2, ipdma.model.onestage(y = y, study = studyid, treat = treat,\n X = cbind(w1, w2), \n response = \"binomial\", \n shrinkage = \"laplace\"), \n type = \"random\", hy.prior = list(\"dunif\", 0, 1))\n\nipd2$model.JAGS\n\nfunction () \n{\n for (i in 1:Np) {\n y[i] ~ dbern(p[i])\n logit(p[i]) <- alpha[studyid[i]] + inprod(beta[], X[i, \n ]) + (1 - equals(treat[i], 1)) * inprod(gamma[], \n X[i, ]) + d[studyid[i], treat[i]]\n }\n for (j in 1:Nstudies) {\n d[j, 1] <- 0\n d[j, 2] ~ dnorm(delta[2], tau)\n }\n sd ~ dnorm(0, 1)\n T(0, )\n tau <- pow(sd, -2)\n delta[1] <- 0\n delta[2] ~ dnorm(0, 0.001)\n for (j in 1:Nstudies) {\n alpha[j] ~ dnorm(0, 0.001)\n }\n for (k in 1:Ncovariate) {\n beta[k] ~ dnorm(0, 0.001)\n }\n tt <- lambda\n lambda <- pow(lambda.inv, -1)\n lambda.inv ~ dunif(0, 5)\n for (k in 1:Ncovariate) {\n gamma[k] ~ ddexp(0, tt)\n }\n}\n<environment: 0x55f3db4139b0>\n\n\n\nsamples <- ipd.run(ipd2, n.chains = 2, n.iter = 20, \n pars.save = c(\"alpha\", \"beta\", \"delta\", \"sd\", \"gamma\"))\nsummary(samples)\n\n\n\n\nIterations = 2001:2020\nThinning interval = 1 \nNumber of chains = 2 \nSample size per chain = 20 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\nalpha[1] -0.26478 0.28335 0.04480 0.05551\nalpha[2] -0.41666 0.23180 0.03665 0.02909\nalpha[3] -0.39071 0.21151 0.03344 0.05258\nalpha[4] -0.49347 0.20642 0.03264 0.03819\nalpha[5] -0.25525 0.18252 0.02886 0.02923\nalpha[6] -0.41317 0.18360 0.02903 0.03677\nbeta[1] -0.03952 0.09834 0.01555 0.01863\nbeta[2] 0.15088 0.07552 0.01194 0.01427\ndelta[1] 0.00000 0.00000 0.00000 0.00000\ndelta[2] 0.21968 0.26395 0.04173 0.05528\ngamma[1] -0.06718 0.09728 0.01538 0.01399\ngamma[2] -0.02296 0.08799 0.01391 0.02269\nsd 0.50242 0.29347 0.04640 0.12223\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\nalpha[1] -0.69162 -0.43794 -0.26726 -0.05156 0.13615\nalpha[2] -0.80799 -0.57288 -0.45067 -0.24694 -0.02281\nalpha[3] -0.71852 -0.52968 -0.43582 -0.21166 -0.03799\nalpha[4] -0.79019 -0.63515 -0.51543 -0.39219 -0.08663\nalpha[5] -0.65705 -0.34258 -0.25473 -0.14453 0.06589\nalpha[6] -0.71876 -0.53727 -0.41474 -0.26524 -0.11858\nbeta[1] -0.21552 -0.10699 -0.04432 0.01984 0.17738\nbeta[2] 0.02627 0.08576 0.13895 0.20557 0.27684\ndelta[1] 0.00000 0.00000 0.00000 0.00000 0.00000\ndelta[2] -0.19506 0.02491 0.21958 0.39657 0.69399\ngamma[1] -0.31413 -0.07879 -0.03702 -0.01768 0.04176\ngamma[2] -0.18747 -0.06206 -0.01492 0.01069 0.13327\nsd 0.14954 0.21615 0.43839 0.72114 0.98677\n\n\nThe predicted treatment benefit for a new patient with covariates w1 = 1.6 and w2 = 1.3 is given as:\n\nround(treatment.effect(ipd2, samples, newpatient = c(w1 = 1.6, w2 = 1.3)), 2)\n\n0.025 0.5 0.975 \n 0.65 1.08 1.93 \n\n\nIn other words, the aforementioned patient 1.08 (95% Credibility Interval: 0.65 to 1.93)" + "text": "9.1 Estimating heterogeneous treatment effects in pairwise meta-analysis\nWe hereby provide code for estimating patient-level treatment effects for the case when we have patient-level data from multiple randomized trials.\n\n9.1.1 Example of a continuous outcome\n\n9.1.1.1 Setup\nWe start by simulating an artificial dataset using the R package bipd:\n\nlibrary(bipd)\nds <- generate_ipdma_example(type = \"continuous\")\n\nLet us have a look at the dataset:\n\nhead(ds)\n\n studyid treat z1 z2 y\n1 1 1 -1.0619070 0.5036365 9\n2 1 0 0.6982086 -0.8906105 11\n3 1 0 -1.3479618 1.3276495 11\n4 1 0 -0.7654394 1.2064922 11\n5 1 1 -0.8290456 0.5130794 8\n6 1 0 -0.4027927 -1.5423636 11\n\n\nThe simulated dataset contains information on the following variables:\n\nthe trial indicator studyid\nthe treatment indicator treat, which takes the values 0 for control and 1 for active treatment\ntwo prognostic variables z1 and z2\nthe continuous outcome y\n\n\n\n\n\n\n\nTable 9.1: The simulated dataset with a continuous outcome\n\n\n\n\n\n\n\n\n\n0\n(N=296)\n1\n(N=304)\nOverall\n(N=600)\n\n\n\n\nz1\n\n\n\n\n\nMean (SD)\n0.0145 (1.04)\n0.0104 (1.07)\n0.0124 (1.05)\n\n\nMedian [Min, Max]\n0.0271 [-2.62, 2.69]\n-0.00402 [-2.18, 3.15]\n0.00818 [-2.62, 3.15]\n\n\nz2\n\n\n\n\n\nMean (SD)\n-0.0210 (1.01)\n-0.0459 (1.00)\n-0.0336 (1.01)\n\n\nMedian [Min, Max]\n-0.0340 [-2.90, 3.04]\n-0.0599 [-2.91, 3.16]\n-0.0448 [-2.91, 3.16]\n\n\nstudyid\n\n\n\n\n\n1\n48 (16.2%)\n52 (17.1%)\n100 (16.7%)\n\n\n2\n50 (16.9%)\n50 (16.4%)\n100 (16.7%)\n\n\n3\n55 (18.6%)\n45 (14.8%)\n100 (16.7%)\n\n\n4\n46 (15.5%)\n54 (17.8%)\n100 (16.7%)\n\n\n5\n47 (15.9%)\n53 (17.4%)\n100 (16.7%)\n\n\n6\n50 (16.9%)\n50 (16.4%)\n100 (16.7%)\n\n\n\n\n\n\n\n\n\n\n9.1.1.2 Model fitting\nWe synthesize the evidence using a Bayesian random effects meta-analysis model. The model is given in Equation 16.7 of the book. First we need set up the data and create the model:\n\nipd <- with(ds, ipdma.model.onestage(y = y, study = studyid, treat = treat,\n X = cbind(z1, z2), \n response = \"normal\", \n shrinkage = \"none\"), \n type = \"random\")\n\nThe JAGS model can be accessed as follows:\n\nipd$model.JAGS\n\nfunction () \n{\n for (i in 1:Np) {\n y[i] ~ dnorm(mu[i], sigma)\n mu[i] <- alpha[studyid[i]] + inprod(beta[], X[i, ]) + \n (1 - equals(treat[i], 1)) * inprod(gamma[], X[i, \n ]) + d[studyid[i], treat[i]]\n }\n sigma ~ dgamma(0.001, 0.001)\n for (j in 1:Nstudies) {\n d[j, 1] <- 0\n d[j, 2] ~ dnorm(delta[2], tau)\n }\n sd ~ dnorm(0, 1)\n T(0, )\n tau <- pow(sd, -2)\n delta[1] <- 0\n delta[2] ~ dnorm(0, 0.001)\n for (j in 1:Nstudies) {\n alpha[j] ~ dnorm(0, 0.001)\n }\n for (k in 1:Ncovariate) {\n beta[k] ~ dnorm(0, 0.001)\n }\n for (k in 1:Ncovariate) {\n gamma[k] ~ dnorm(0, 0.001)\n }\n}\n<environment: 0x55f00313cef0>\n\n\nWe can fit the treatment effect model as follows:\n\nsamples <- ipd.run(ipd, n.chains = 2, n.iter = 20,\n pars.save = c(\"alpha\", \"beta\", \"delta\", \"sd\", \"gamma\"))\ntrtbenefit <- round(treatment.effect(ipd, samples, newpatient = c(z1 = 1, z2 = 0.5)), 2)\n\nHere are the estimated model parameters:\n\nsummary(samples)\n\n\nIterations = 2001:2020\nThinning interval = 1 \nNumber of chains = 2 \nSample size per chain = 20 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\nalpha[1] 10.9426 0.04692 0.007419 0.009976\nalpha[2] 7.9837 0.05288 0.008362 0.011109\nalpha[3] 10.4769 0.05040 0.007969 0.012380\nalpha[4] 9.6714 0.07061 0.011164 0.016969\nalpha[5] 12.8507 0.04769 0.007541 0.007479\nalpha[6] 15.7810 0.05820 0.009202 0.009394\nbeta[1] 0.1973 0.01854 0.002932 0.002709\nbeta[2] 0.2893 0.02307 0.003648 0.003640\ndelta[1] 0.0000 0.00000 0.000000 0.000000\ndelta[2] -2.6862 0.44311 0.070061 0.069792\ngamma[1] -0.4957 0.02701 0.004270 0.003434\ngamma[2] 0.5759 0.02560 0.004048 0.004050\nsd 1.1100 0.26425 0.041782 0.054422\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\nalpha[1] 10.8718 10.9150 10.9473 10.9736 11.0214\nalpha[2] 7.9085 7.9421 7.9751 8.0237 8.0888\nalpha[3] 10.3921 10.4420 10.4704 10.5069 10.5738\nalpha[4] 9.5354 9.6271 9.6909 9.7153 9.7868\nalpha[5] 12.7619 12.8105 12.8513 12.8843 12.9344\nalpha[6] 15.6756 15.7396 15.7881 15.8253 15.8795\nbeta[1] 0.1616 0.1876 0.1988 0.2075 0.2228\nbeta[2] 0.2468 0.2707 0.2944 0.3057 0.3257\ndelta[1] 0.0000 0.0000 0.0000 0.0000 0.0000\ndelta[2] -3.3771 -2.9628 -2.6712 -2.3931 -2.0242\ngamma[1] -0.5379 -0.5174 -0.4959 -0.4790 -0.4319\ngamma[2] 0.5242 0.5565 0.5765 0.5931 0.6172\nsd 0.7587 0.8959 1.0888 1.2883 1.6156\n\n\n\n\n9.1.1.3 Prection\nWe can now predict the individualized treatment effect for a new patient with covariate values z1 = 1 and z2 = 0.5.\n\nround(treatment.effect(ipd, samples, newpatient = c(z1 = 1, z2 = 0.5)), 2)\n\n0.025 0.5 0.975 \n-3.50 -2.81 -2.17 \n\n\nThis means that the predicted outcome for patient with covariate values z1 = 1 and z2 = 0.5 will differ by -2.81 units when receiving the active treatment (treat = 1) as compared to the control treatment (treat = 0).\nWe can also predict treatment benefit for all patients in the sample, and look at the distribution of predicted benefit.\n\nlibrary(dplyr)\nlibrary(ggplot2)\n\nds <- ds %>% mutate(benefit = NA,\n study = paste(\"Trial\", studyid)) \n\nfor (i in seq(nrow(ds))) {\n newpat <- as.matrix(ds[i, c(\"z1\", \"z2\")])\n ds$benefit[i] <- treatment.effect(ipd, samples, newpatient = newpat)[\"0.5\"]\n}\n\nsummbenefit <- ds %>% group_by(study) %>% \n summarize(mediabenefit = median(benefit), meanbenefit = mean(benefit))\n\nggplot(ds, aes(x = benefit)) + \n geom_histogram(aes(y = after_stat(density)), alpha = 0.3) + \n geom_density() +\n geom_vline(data = summbenefit, aes(xintercept = meanbenefit), \n linewidth = 0.5, lty = 2) + \n facet_wrap(~study) + \n ylab(\"Density\") +\n xlab(\"Predicted treatment benefit\") + theme_bw()\n\n\n\n\nFigure 9.1: Distribution of predicted treatment benefit in each trial. Dashed lines represent the trial mean.\n\n\n\n\n\n\n9.1.1.4 Penalization\nLet us repeat the analysis, but this time while penalizing the treatment-covariate coefficients using a Bayesian LASSO prior.\n\nipd <- with(ds, ipdma.model.onestage(y = y, study = studyid, \n treat = treat,\n X = cbind(z1, z2), \n response = \"normal\", \n shrinkage = \"laplace\"), \n type = \"random\")\n\nsamples <- ipd.run(ipd, n.chains = 2, n.iter = 20, \n pars.save = c(\"alpha\", \"beta\", \"delta\", \"sd\", \"gamma\"))\n\nCompiling model graph\n Resolving undeclared variables\n Allocating nodes\nGraph information:\n Observed stochastic nodes: 600\n Unobserved stochastic nodes: 20\n Total graph size: 6039\n\nInitializing model\n\nround(treatment.effect(ipd, samples, newpatient = c(1,0.5)), 2)\n\n0.025 0.5 0.975 \n-4.37 -2.87 -1.82 \n\n\n\n\n\n9.1.2 Example of a binary outcome\n\n9.1.2.1 Setup\nWe now present the case of a binary outcome. We first generate a dataset as before, using the bipd package.\n\nds2 <- generate_ipdma_example(type = \"binary\")\nhead(ds2)\n\n studyid treat w1 w2 y\n1 1 0 -1.44373045 0.8321901 0\n2 1 1 -0.48748747 0.5844157 0\n3 1 1 -0.39070957 0.2867364 0\n4 1 0 1.38918716 1.0353666 1\n5 1 0 -0.29848976 3.0342741 0\n6 1 1 -0.03002357 2.0635757 1\n\n\nThe simulated dataset contains information on the following variables:\n\nthe trial indicator studyid\nthe treatment indicator treat, which takes the values 0 for control and 1 for active treatment\ntwo prognostic variables w1 and w2\nthe binary outcome y\n\n\n\n\n\n\n\nTable 9.2: The simulated dataset with a binary outcome\n\n\n\n\n\n\n\n\n\n0\n(N=307)\n1\n(N=293)\nOverall\n(N=600)\n\n\n\n\nw1\n\n\n\n\n\nMean (SD)\n0.0271 (0.986)\n-0.0340 (1.04)\n-0.00274 (1.01)\n\n\nMedian [Min, Max]\n0.109 [-3.06, 3.14]\n-0.0394 [-3.09, 2.79]\n0.0257 [-3.09, 3.14]\n\n\nw2\n\n\n\n\n\nMean (SD)\n-0.0220 (1.01)\n0.0431 (0.963)\n0.00978 (0.986)\n\n\nMedian [Min, Max]\n-0.0243 [-3.11, 3.26]\n0.0686 [-2.65, 2.46]\n0.0198 [-3.11, 3.26]\n\n\nstudyid\n\n\n\n\n\n1\n49 (16.0%)\n51 (17.4%)\n100 (16.7%)\n\n\n2\n60 (19.5%)\n40 (13.7%)\n100 (16.7%)\n\n\n3\n49 (16.0%)\n51 (17.4%)\n100 (16.7%)\n\n\n4\n47 (15.3%)\n53 (18.1%)\n100 (16.7%)\n\n\n5\n48 (15.6%)\n52 (17.7%)\n100 (16.7%)\n\n\n6\n54 (17.6%)\n46 (15.7%)\n100 (16.7%)\n\n\n\n\n\n\n\n\n\n\n9.1.2.2 Model fitting\nWe use a Bayesian random effects model with binomial likelihood. This is similar to the model 16.7 of the book, but with a Binomial likelihood, i.e. \n\\[\ny_{ij}\\sim \\text{Binomial}(\\pi_{ij}) \\\\\n\\] \\[\n\\text{logit}(\\pi_{ij})=a_j+\\delta_j t_{ij}+ \\sum_{l=1}^{L}\\beta_l x_{ij}+ \\sum_{l=1}^{L}\\gamma_l x_{ij} t_{ij}\n\\] The remaining of the model is as in the book. We can penalize the estimated parameters for effect modification (\\(\\gamma\\)’s), using a Bayesian LASSO. We can do this using again the bipd package:\n\nipd2 <- with(ds2, ipdma.model.onestage(y = y, study = studyid, treat = treat,\n X = cbind(w1, w2), \n response = \"binomial\", \n shrinkage = \"laplace\"), \n type = \"random\", hy.prior = list(\"dunif\", 0, 1))\n\nipd2$model.JAGS\n\nfunction () \n{\n for (i in 1:Np) {\n y[i] ~ dbern(p[i])\n logit(p[i]) <- alpha[studyid[i]] + inprod(beta[], X[i, \n ]) + (1 - equals(treat[i], 1)) * inprod(gamma[], \n X[i, ]) + d[studyid[i], treat[i]]\n }\n for (j in 1:Nstudies) {\n d[j, 1] <- 0\n d[j, 2] ~ dnorm(delta[2], tau)\n }\n sd ~ dnorm(0, 1)\n T(0, )\n tau <- pow(sd, -2)\n delta[1] <- 0\n delta[2] ~ dnorm(0, 0.001)\n for (j in 1:Nstudies) {\n alpha[j] ~ dnorm(0, 0.001)\n }\n for (k in 1:Ncovariate) {\n beta[k] ~ dnorm(0, 0.001)\n }\n tt <- lambda\n lambda <- pow(lambda.inv, -1)\n lambda.inv ~ dunif(0, 5)\n for (k in 1:Ncovariate) {\n gamma[k] ~ ddexp(0, tt)\n }\n}\n<environment: 0x55f006ccacf8>\n\n\n\nsamples <- ipd.run(ipd2, n.chains = 2, n.iter = 20, \n pars.save = c(\"alpha\", \"beta\", \"delta\", \"sd\", \"gamma\"))\nsummary(samples)\n\n\n\n\nIterations = 2001:2020\nThinning interval = 1 \nNumber of chains = 2 \nSample size per chain = 20 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\nalpha[1] -0.2240404 0.2760 0.04364 0.08409\nalpha[2] -0.1687645 0.2126 0.03361 0.02758\nalpha[3] -0.2222803 0.3359 0.05311 0.06876\nalpha[4] 0.0463834 0.2229 0.03525 0.03404\nalpha[5] -0.2382940 0.2900 0.04585 0.07655\nalpha[6] -0.1147828 0.1944 0.03073 0.04473\nbeta[1] 0.0003677 0.1176 0.01860 0.03548\nbeta[2] 0.0226707 0.1122 0.01775 0.03231\ndelta[1] 0.0000000 0.0000 0.00000 0.00000\ndelta[2] -0.3749353 0.2695 0.04262 0.05488\ngamma[1] -0.1942823 0.1682 0.02660 0.04440\ngamma[2] 0.1003532 0.1587 0.02509 0.04717\nsd 0.3751175 0.2322 0.03671 0.08225\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\nalpha[1] -0.64744 -0.49202 -0.159281 0.03591 0.11782\nalpha[2] -0.47012 -0.33549 -0.183885 0.04210 0.12768\nalpha[3] -0.80523 -0.45864 -0.234532 -0.03354 0.50730\nalpha[4] -0.30353 -0.12156 0.043911 0.22654 0.38940\nalpha[5] -0.76405 -0.37814 -0.203506 -0.04570 0.36505\nalpha[6] -0.39156 -0.26771 -0.145874 0.05104 0.19871\nbeta[1] -0.21175 -0.07668 0.006964 0.09062 0.17487\nbeta[2] -0.18305 -0.03635 0.029703 0.09392 0.20854\ndelta[1] 0.00000 0.00000 0.000000 0.00000 0.00000\ndelta[2] -0.79043 -0.57343 -0.373913 -0.18370 0.03467\ngamma[1] -0.49429 -0.29727 -0.193305 -0.10370 0.14106\ngamma[2] -0.12009 -0.03013 0.092282 0.23293 0.41927\nsd 0.08385 0.24992 0.315429 0.41433 0.86084\n\n\nThe predicted treatment benefit for a new patient with covariates w1 = 1.6 and w2 = 1.3 is given as:\n\nround(treatment.effect(ipd2, samples, newpatient = c(w1 = 1.6, w2 = 1.3)), 2)\n\n0.025 0.5 0.975 \n 0.30 0.60 1.29 \n\n\nIn other words, the aforementioned patient 0.6 (95% Credibility Interval: 0.3 to 1.29)" }, { "objectID": "chapter_16.html#estimating-heterogeous-treatment-effects-in-network-meta-analysis", "href": "chapter_16.html#estimating-heterogeous-treatment-effects-in-network-meta-analysis", "title": "9  Prediction of individual treatment effect using data from multiple studies", "section": "9.2 Estimating heterogeous treatment effects in network meta-analysis", - "text": "9.2 Estimating heterogeous treatment effects in network meta-analysis\n\n9.2.1 Example of a continuous outcome\n\n9.2.1.1 Setup\nWe use again the bipd package to simulate a dataset:\n\nds3 <- generate_ipdnma_example(type = \"continuous\")\nhead(ds3)\n\n studyid treat z1 z2 y\n1 1 2 -0.58562548 -0.7293231 8\n2 1 1 -0.03621696 0.6291016 11\n3 1 1 1.65265173 -0.8750261 11\n4 1 1 2.00171606 -1.0519276 11\n5 1 1 -1.06157061 0.5212684 11\n6 1 1 -0.02835944 0.4339892 11\n\n\nLet us look into the data a bit in more detail:\n\n\n\n\n\n\nTable 9.3: The simulated dataset with a continuous outcome\n\n\n\n\n\n\n\n\n\n\n1\n(N=341)\n2\n(N=348)\n3\n(N=311)\nOverall\n(N=1000)\n\n\n\n\nz1\n\n\n\n\n\n\nMean (SD)\n-0.0264 (0.996)\n-0.0351 (1.03)\n0.0866 (1.00)\n0.00572 (1.01)\n\n\nMedian [Min, Max]\n-0.0520 [-3.08, 2.84]\n-0.0398 [-2.68, 3.05]\n0.0133 [-3.32, 3.26]\n-0.0303 [-3.32, 3.26]\n\n\nz2\n\n\n\n\n\n\nMean (SD)\n-0.00628 (0.962)\n-0.0191 (1.01)\n-0.0157 (1.04)\n-0.0137 (1.00)\n\n\nMedian [Min, Max]\n0.0476 [-2.56, 2.75]\n-0.0667 [-3.14, 2.46]\n-0.0628 [-3.23, 3.46]\n-0.00601 [-3.23, 3.46]\n\n\nstudyid\n\n\n\n\n\n\n1\n47 (13.8%)\n53 (15.2%)\n0 (0%)\n100 (10.0%)\n\n\n2\n56 (16.4%)\n44 (12.6%)\n0 (0%)\n100 (10.0%)\n\n\n3\n43 (12.6%)\n57 (16.4%)\n0 (0%)\n100 (10.0%)\n\n\n4\n52 (15.2%)\n0 (0%)\n48 (15.4%)\n100 (10.0%)\n\n\n5\n45 (13.2%)\n0 (0%)\n55 (17.7%)\n100 (10.0%)\n\n\n6\n0 (0%)\n46 (13.2%)\n54 (17.4%)\n100 (10.0%)\n\n\n7\n0 (0%)\n42 (12.1%)\n58 (18.6%)\n100 (10.0%)\n\n\n8\n32 (9.4%)\n30 (8.6%)\n38 (12.2%)\n100 (10.0%)\n\n\n9\n34 (10.0%)\n39 (11.2%)\n27 (8.7%)\n100 (10.0%)\n\n\n10\n32 (9.4%)\n37 (10.6%)\n31 (10.0%)\n100 (10.0%)\n\n\n\n\n\n\n\n\n\n\n9.2.1.2 Model fitting\nWe will use the model shown in Equation 16.8 in the book. In addition, we will use Bayesian LASSO to penalize the treatment-covariate interactions.\n\nipd3 <- with(ds3, ipdnma.model.onestage(y = y, study = studyid, treat = treat, \n X = cbind(z1, z2), \n response = \"normal\", \n shrinkage = \"laplace\", \n type = \"random\"))\nipd3$model.JAGS\n\nfunction () \n{\n for (i in 1:Np) {\n y[i] ~ dnorm(mu[i], sigma)\n mu[i] <- alpha[studyid[i]] + inprod(beta[], X[i, ]) + \n inprod(gamma[treat[i], ], X[i, ]) + d[studyid[i], \n treatment.arm[i]]\n }\n sigma ~ dgamma(0.001, 0.001)\n for (i in 1:Nstudies) {\n w[i, 1] <- 0\n d[i, 1] <- 0\n for (k in 2:na[i]) {\n d[i, k] ~ dnorm(mdelta[i, k], taudelta[i, k])\n mdelta[i, k] <- delta[t[i, k]] - delta[t[i, 1]] + \n sw[i, k]\n taudelta[i, k] <- tau * 2 * (k - 1)/k\n w[i, k] <- d[i, k] - delta[t[i, k]] + delta[t[i, \n 1]]\n sw[i, k] <- sum(w[i, 1:(k - 1)])/(k - 1)\n }\n }\n sd ~ dnorm(0, 1)\n T(0, )\n tau <- pow(sd, -2)\n delta[1] <- 0\n for (k in 2:Ntreat) {\n delta[k] ~ dnorm(0, 0.001)\n }\n for (j in 1:Nstudies) {\n alpha[j] ~ dnorm(0, 0.001)\n }\n for (k in 1:Ncovariate) {\n beta[k] ~ dnorm(0, 0.001)\n }\n lambda[1] <- 0\n lambda.inv[1] <- 0\n for (m in 2:Ntreat) {\n tt[m] <- lambda[m] * sigma\n lambda[m] <- pow(lambda.inv[m], -1)\n lambda.inv[m] ~ dunif(0, 5)\n }\n for (k in 1:Ncovariate) {\n gamma[1, k] <- 0\n for (m in 2:Ntreat) {\n gamma[m, k] ~ ddexp(0, tt[m])\n }\n }\n}\n<environment: 0x55f3db6ab4c8>\n\nsamples <- ipd.run(ipd3, n.chains = 2, n.iter = 20, \n pars.save = c(\"alpha\", \"beta\", \"delta\", \"sd\", \"gamma\"))\n\nCompiling model graph\n Resolving undeclared variables\n Allocating nodes\nGraph information:\n Observed stochastic nodes: 1000\n Unobserved stochastic nodes: 35\n Total graph size: 10141\n\nInitializing model\n\nsummary(samples)\n\n\nIterations = 2001:2020\nThinning interval = 1 \nNumber of chains = 2 \nSample size per chain = 20 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\nalpha[1] 10.99534 0.04944 0.007816 0.010662\nalpha[2] 7.97976 0.05151 0.008144 0.009861\nalpha[3] 10.44126 0.04455 0.007044 0.006742\nalpha[4] 9.63265 0.05314 0.008402 0.015169\nalpha[5] 12.80789 0.04337 0.006857 0.009947\nalpha[6] 13.10793 0.05194 0.008212 0.014386\nalpha[7] 7.42342 0.03885 0.006142 0.009881\nalpha[8] 11.09641 0.04057 0.006414 0.009031\nalpha[9] 10.09190 0.05934 0.009382 0.010856\nalpha[10] 9.20245 0.05088 0.008044 0.013538\nbeta[1] 0.19888 0.01488 0.002352 0.005494\nbeta[2] 0.32908 0.01677 0.002652 0.005854\ndelta[1] 0.00000 0.00000 0.000000 0.000000\ndelta[2] -2.95250 0.03362 0.005316 0.005333\ndelta[3] -1.11629 0.04667 0.007379 0.014658\ngamma[1,1] 0.00000 0.00000 0.000000 0.000000\ngamma[2,1] -0.61115 0.02507 0.003963 0.007741\ngamma[3,1] -0.29809 0.02267 0.003585 0.007344\ngamma[1,2] 0.00000 0.00000 0.000000 0.000000\ngamma[2,2] 0.58568 0.02548 0.004029 0.006822\ngamma[3,2] 0.41651 0.02459 0.003887 0.006797\nsd 0.07894 0.03147 0.004976 0.007731\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\nalpha[1] 10.91186 10.96479 10.98757 11.0358 11.0780\nalpha[2] 7.88207 7.94564 7.98290 8.0078 8.0832\nalpha[3] 10.34906 10.41524 10.43860 10.4739 10.5233\nalpha[4] 9.51890 9.59978 9.63523 9.6703 9.7067\nalpha[5] 12.73284 12.78053 12.81198 12.8463 12.8846\nalpha[6] 13.02121 13.06565 13.10716 13.1477 13.1969\nalpha[7] 7.35202 7.39341 7.42084 7.4507 7.4935\nalpha[8] 11.03713 11.06940 11.08430 11.1219 11.1777\nalpha[9] 9.97948 10.04921 10.08597 10.1286 10.1887\nalpha[10] 9.12155 9.16920 9.20311 9.2335 9.3087\nbeta[1] 0.17041 0.19042 0.20031 0.2083 0.2241\nbeta[2] 0.30087 0.31601 0.32796 0.3422 0.3562\ndelta[1] 0.00000 0.00000 0.00000 0.0000 0.0000\ndelta[2] -2.99962 -2.97157 -2.95677 -2.9358 -2.8790\ndelta[3] -1.17731 -1.16032 -1.11565 -1.0866 -1.0207\ngamma[1,1] 0.00000 0.00000 0.00000 0.0000 0.0000\ngamma[2,1] -0.66340 -0.62382 -0.60841 -0.5984 -0.5549\ngamma[3,1] -0.35309 -0.30967 -0.29325 -0.2809 -0.2662\ngamma[1,2] 0.00000 0.00000 0.00000 0.0000 0.0000\ngamma[2,2] 0.52196 0.57758 0.58452 0.6017 0.6207\ngamma[3,2] 0.36857 0.40146 0.41455 0.4362 0.4557\nsd 0.03865 0.05792 0.06804 0.1023 0.1334\n\n\nAs before, we can use the treatment.effect() function of bipd to estimate relative effects for new patients.\n\ntreatment.effect(ipd3, samples, newpatient= c(1,2))\n\n$`treatment 2`\n 0.025 0.5 0.975 \n-2.515622 -2.374636 -2.277547 \n\n$`treatment 3`\n 0.025 0.5 0.975 \n-0.6654101 -0.5668239 -0.4414406 \n\n\nThis gives us the relative effects for all treatments versus the reference. To obtain relative effects between active treatments we need some more coding:\n\nsamples.all=data.frame(rbind(samples[[1]], samples[[2]]))\nnewpatient= c(1,2)\nnewpatient <- (newpatient - ipd3$scale_mean)/ipd3$scale_sd\n\nmedian(\n samples.all$delta.2.+samples.all$gamma.2.1.*\n newpatient[1]+samples.all$gamma.2.2.*newpatient[2]\n-\n (samples.all$delta.3.+samples.all$gamma.3.1.*newpatient[1]+\n samples.all$gamma.3.2.*newpatient[2])\n)\n\n[1] -1.798048\n\nquantile(samples.all$delta.2.+samples.all$gamma.2.1.*\n newpatient[1]+samples.all$gamma.2.2.*newpatient[2]\n -(samples.all$delta.3.+samples.all$gamma.3.1.*newpatient[1]+\n samples.all$gamma.3.2.*newpatient[2])\n , probs = 0.025)\n\n 2.5% \n-1.928005 \n\nquantile(samples.all$delta.2.+samples.all$gamma.2.1.*\n newpatient[1]+samples.all$gamma.2.2.*newpatient[2]\n -(samples.all$delta.3.+samples.all$gamma.3.1.*newpatient[1]+\n samples.all$gamma.3.2.*newpatient[2])\n , probs = 0.975)\n\n 97.5% \n-1.658725 \n\n\n\n\n\n9.2.2 Modeling patient-level relative effects using randomized and observational evidence for a network of treatments\nWe will now follow Chapter 16.3.5 from the book. In this analysis we will not use penalization, and we will assume fixed effects. For an example with penalization and random effects, see part 2 of this vignettte.\n\n9.2.2.1 Setup\nWe generate a very simple dataset of three studies comparing three treatments. We will assume 2 RCTs and 1 non-randomized trial:\n\nds4 <- generate_ipdnma_example(type = \"continuous\")\nds4 <- ds4 %>% filter(studyid %in% c(1,4,10)) %>%\n mutate(studyid = factor(studyid) %>%\n recode_factor(\n \"1\" = \"1\",\n \"4\" = \"2\",\n \"10\" = \"3\"),\n design = ifelse(studyid == \"3\", \"nrs\", \"rct\"))\n\nThe sample size is as follows:\n\n\n \n s1 s2 s3\n treat A: 49 42 33\n treat B: 51 0 34\n treat C: 0 58 33\n\n\n\n\n9.2.2.2 Model fitting\nWe will use the design-adjusted model, equation 16.9 in the book. We will fit a two-stage fixed effects meta-analysis and we will use a variance inflation factor. The code below is used to specify the analysis of each individual study. Briefly, in each study we adjust the treatment effect for the prognostic factors z1 and z2, as well as their interaction with treat.\n\nlibrary(rjags)\n\nLoading required package: coda\n\n\nLinked to JAGS 4.3.0\n\n\nLoaded modules: basemod,bugs\n\nfirst.stage <- \"\nmodel{\n\nfor (i in 1:N){\n y[i] ~ dnorm(mu[i], tau) \n mu[i] <- a + inprod(b[], X[i,]) + inprod(c[,treat[i]], X[i,]) + d[treat[i]] \n}\nsigma ~ dunif(0, 5)\ntau <- pow(sigma, -2)\n\na ~ dnorm(0, 0.001)\n\nfor(k in 1:Ncovariate){\n b[k] ~ dnorm(0,0.001)\n}\n\nfor(k in 1:Ncovariate){\n c[k,1] <- 0\n}\n\ntauGamma <- pow(sdGamma,-1)\nsdGamma ~ dunif(0, 5)\n\nfor(k in 1:Ncovariate){\n for(t in 2:Ntreat){\n c[k,t] ~ ddexp(0, tauGamma)\n }\n}\n\nd[1] <- 0\nfor(t in 2:Ntreat){\n d[t] ~ dnorm(0, 0.001)\n}\n}\"\n\nSubsequently, we estimate the relative treatment effects in the first (randomized) study comparing treatments A and B:\n\nmodel1.spec <- textConnection(first.stage) \ndata1 <- with(ds4 %>% filter(studyid == 1), \n list(y = y,\n N = length(y), \n X = cbind(z1,z2), \n treat = treat,\n Ncovariate = 2, \n Ntreat = 2))\njags.m <- jags.model(model1.spec, data = data1, n.chains = 2, n.adapt = 500,\n quiet = TRUE)\nparams <- c(\"d\", \"c\") \nsamps4.1 <- coda.samples(jags.m, params, n.iter = 50)\nsamps.all.s1 <- data.frame(as.matrix(samps4.1))\n\nsamps.all.s1 <- samps.all.s1[, c(\"c.1.2.\", \"c.2.2.\", \"d.2.\")]\ndelta.1 <- colMeans(samps.all.s1)\ncov.1 <- var(samps.all.s1)\n\nWe repeat the analysis for the second (randomized) study comparing treatments A and C:\n\nmodel1.spec <- textConnection(first.stage) \ndata2 <- with(ds4 %>% filter(studyid == 2), \n list(y = y,\n N = length(y), \n X = cbind(z1,z2), \n treat = ifelse(treat == 3, 2, treat),\n Ncovariate = 2, \n Ntreat = 2))\njags.m <- jags.model(model1.spec, data = data2, n.chains = 2, n.adapt = 100,\n quiet = TRUE)\nparams <- c(\"d\", \"c\") \nsamps4.2 <- coda.samples(jags.m, params, n.iter = 50)\nsamps.all.s2 <- data.frame(as.matrix(samps4.2))\nsamps.all.s2 <- samps.all.s2[, c(\"c.1.2.\", \"c.2.2.\", \"d.2.\")]\ndelta.2 <- colMeans(samps.all.s2)\ncov.2 <- var(samps.all.s2)\n\nFinally, we analyze the third (non-randomized) study comparing treatments A, B, and C:\n\nmodel1.spec <- textConnection(first.stage) \ndata3 <- with(ds4 %>% filter(studyid == 3), \n list(y = y,\n N = length(y), \n X = cbind(z1,z2), \n treat = treat,\n Ncovariate = 2, \n Ntreat = 3))\njags.m <- jags.model(model1.spec, data = data3, n.chains = 2, n.adapt = 100,\n quiet = TRUE)\nparams <- c(\"d\", \"c\") \nsamps4.3 <- coda.samples(jags.m, params, n.iter = 50)\nsamps.all.s3 <- data.frame(as.matrix(samps4.3))\n\nsamps.all.s3 <- samps.all.s3[, c(\"c.1.2.\", \"c.2.2.\", \"d.2.\", \"c.1.3.\", \n \"c.2.3.\", \"d.3.\")]\ndelta.3 <- colMeans(samps.all.s3)\ncov.3 <- var(samps.all.s3)\n\nThe corresponding treatment effect estimates are depicted below:\n\n\n\n\nTable 9.4: Treatment effect estimates.\n\n\nstudy\nB versus A\nC versus A\n\n\n\n\nstudy 1\n-2.954 (SE = 0.049 )\n\n\n\nstudy 2\n\n-0.978 (SE = 0.050 )\n\n\nstudy 3\n-2.949 (SE = 0.075 )\n-1.143 (SE = 0.074 )\n\n\n\n\n\n\n\n\nWe can now fit the second stage of the network meta-analysis. The corresponding JAGS model is specified below:\n\nsecond.stage <-\n\"model{\n \n #likelihood\n y1 ~ dmnorm(Mu1, Omega1)\n y2 ~ dmnorm(Mu2, Omega2)\n y3 ~ dmnorm(Mu3, Omega3*W)\n\n \n Omega1 <- inverse(cov.1)\n Omega2 <- inverse(cov.2)\n Omega3 <- inverse(cov.3)\n\n Mu1 <- c(gamma[,1], delta[2])\n Mu2 <- c(gamma[,2], delta[3]) \n Mu3 <- c(gamma[,1], delta[2],gamma[,2], delta[3])\n \n #parameters\n for(i in 1:2){\n gamma[i,1] ~ dnorm(0, 0.001)\n gamma[i,2] ~ dnorm(0, 0.001)\n }\n \n delta[1] <- 0\n delta[2] ~ dnorm(0, 0.001)\n delta[3] ~ dnorm(0, 0.001)\n \n}\n\"\n\nWe can fit as follows:\n\nmodel1.spec <- textConnection(second.stage) \ndata3 <- list(y1 = delta.1, y2 = delta.2, y3 = delta.3, \n cov.1 = cov.1, cov.2 = cov.2, cov.3 = cov.3, W = 0.5)\n\njags.m <- jags.model(model1.spec, data = data3, n.chains = 2, n.adapt = 50,\n quiet = TRUE)\nparams <- c(\"delta\", \"gamma\") \nsamps4.3 <- coda.samples(jags.m, params, n.iter = 50)\n\n\nsummary(samps4.3)\n\n\nIterations = 1:50\nThinning interval = 1 \nNumber of chains = 2 \nSample size per chain = 50 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\ndelta[1] 0.0000 0.00000 0.000000 0.000000\ndelta[2] -2.9539 0.04438 0.004438 0.004460\ndelta[3] -1.0464 0.04031 0.004031 0.004578\ngamma[1,1] -0.7884 0.04451 0.004451 0.005232\ngamma[2,1] 0.8241 0.04826 0.004826 0.003472\ngamma[1,2] -0.4829 0.04746 0.004746 0.005439\ngamma[2,2] 0.4202 0.06225 0.006225 0.006242\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\ndelta[1] 0.0000 0.0000 0.0000 0.0000 0.0000\ndelta[2] -3.0358 -2.9799 -2.9585 -2.9247 -2.8551\ndelta[3] -1.1206 -1.0742 -1.0518 -1.0136 -0.9749\ngamma[1,1] -0.8690 -0.8149 -0.7956 -0.7535 -0.6997\ngamma[2,1] 0.7411 0.7899 0.8294 0.8533 0.9296\ngamma[1,2] -0.5698 -0.5159 -0.4810 -0.4449 -0.3959\ngamma[2,2] 0.3278 0.3818 0.4117 0.4580 0.5474\n\n# calculate treatment effects\nsamples.all = data.frame(rbind(samps4.3[[1]], samps4.3[[2]]))\nnewpatient = c(1,2)\n\nmedian(\n samples.all$delta.2. + samples.all$gamma.1.1.*newpatient[1] +\n samples.all$gamma.2.1.*newpatient[2]\n)\n\n[1] -2.096024\n\nquantile(samples.all$delta.2.+samples.all$gamma.1.1.*newpatient[1]+\n samples.all$gamma.2.1.*newpatient[2]\n , probs = 0.025)\n\n 2.5% \n-2.27708 \n\nquantile(samples.all$delta.2.+samples.all$gamma.1.1.*newpatient[1]+\n samples.all$gamma.2.1.*newpatient[2]\n , probs = 0.975)\n\n 97.5% \n-1.855506" + "text": "9.2 Estimating heterogeous treatment effects in network meta-analysis\n\n9.2.1 Example of a continuous outcome\n\n9.2.1.1 Setup\nWe use again the bipd package to simulate a dataset:\n\nds3 <- generate_ipdnma_example(type = \"continuous\")\nhead(ds3)\n\n studyid treat z1 z2 y\n1 1 2 0.8257795 0.7993777 8\n2 1 2 1.2084989 0.7265650 8\n3 1 2 -0.1500272 0.2549846 8\n4 1 1 1.2103609 -0.4187725 11\n5 1 2 -0.7352842 0.6690007 9\n6 1 1 0.4432094 -0.1226550 11\n\n\nLet us look into the data a bit in more detail:\n\n\n\n\n\n\nTable 9.3: The simulated dataset with a continuous outcome\n\n\n\n\n\n\n\n\n\n\n1\n(N=328)\n2\n(N=358)\n3\n(N=314)\nOverall\n(N=1000)\n\n\n\n\nz1\n\n\n\n\n\n\nMean (SD)\n0.108 (1.05)\n-0.0196 (1.03)\n0.0531 (0.999)\n0.0451 (1.03)\n\n\nMedian [Min, Max]\n0.0770 [-2.24, 3.51]\n-0.0210 [-3.19, 2.84]\n0.0176 [-2.82, 2.59]\n0.0163 [-3.19, 3.51]\n\n\nz2\n\n\n\n\n\n\nMean (SD)\n0.0505 (0.955)\n-0.125 (1.06)\n0.0315 (1.01)\n-0.0183 (1.01)\n\n\nMedian [Min, Max]\n-0.00987 [-2.88, 2.61]\n-0.0897 [-2.99, 2.60]\n0.0626 [-2.88, 2.26]\n-0.0261 [-2.99, 2.61]\n\n\nstudyid\n\n\n\n\n\n\n1\n47 (14.3%)\n53 (14.8%)\n0 (0%)\n100 (10.0%)\n\n\n2\n49 (14.9%)\n51 (14.2%)\n0 (0%)\n100 (10.0%)\n\n\n3\n45 (13.7%)\n55 (15.4%)\n0 (0%)\n100 (10.0%)\n\n\n4\n46 (14.0%)\n0 (0%)\n54 (17.2%)\n100 (10.0%)\n\n\n5\n44 (13.4%)\n0 (0%)\n56 (17.8%)\n100 (10.0%)\n\n\n6\n0 (0%)\n54 (15.1%)\n46 (14.6%)\n100 (10.0%)\n\n\n7\n0 (0%)\n48 (13.4%)\n52 (16.6%)\n100 (10.0%)\n\n\n8\n29 (8.8%)\n34 (9.5%)\n37 (11.8%)\n100 (10.0%)\n\n\n9\n32 (9.8%)\n32 (8.9%)\n36 (11.5%)\n100 (10.0%)\n\n\n10\n36 (11.0%)\n31 (8.7%)\n33 (10.5%)\n100 (10.0%)\n\n\n\n\n\n\n\n\n\n\n9.2.1.2 Model fitting\nWe will use the model shown in Equation 16.8 in the book. In addition, we will use Bayesian LASSO to penalize the treatment-covariate interactions.\n\nipd3 <- with(ds3, ipdnma.model.onestage(y = y, study = studyid, treat = treat, \n X = cbind(z1, z2), \n response = \"normal\", \n shrinkage = \"laplace\", \n type = \"random\"))\nipd3$model.JAGS\n\nfunction () \n{\n for (i in 1:Np) {\n y[i] ~ dnorm(mu[i], sigma)\n mu[i] <- alpha[studyid[i]] + inprod(beta[], X[i, ]) + \n inprod(gamma[treat[i], ], X[i, ]) + d[studyid[i], \n treatment.arm[i]]\n }\n sigma ~ dgamma(0.001, 0.001)\n for (i in 1:Nstudies) {\n w[i, 1] <- 0\n d[i, 1] <- 0\n for (k in 2:na[i]) {\n d[i, k] ~ dnorm(mdelta[i, k], taudelta[i, k])\n mdelta[i, k] <- delta[t[i, k]] - delta[t[i, 1]] + \n sw[i, k]\n taudelta[i, k] <- tau * 2 * (k - 1)/k\n w[i, k] <- d[i, k] - delta[t[i, k]] + delta[t[i, \n 1]]\n sw[i, k] <- sum(w[i, 1:(k - 1)])/(k - 1)\n }\n }\n sd ~ dnorm(0, 1)\n T(0, )\n tau <- pow(sd, -2)\n delta[1] <- 0\n for (k in 2:Ntreat) {\n delta[k] ~ dnorm(0, 0.001)\n }\n for (j in 1:Nstudies) {\n alpha[j] ~ dnorm(0, 0.001)\n }\n for (k in 1:Ncovariate) {\n beta[k] ~ dnorm(0, 0.001)\n }\n lambda[1] <- 0\n lambda.inv[1] <- 0\n for (m in 2:Ntreat) {\n tt[m] <- lambda[m] * sigma\n lambda[m] <- pow(lambda.inv[m], -1)\n lambda.inv[m] ~ dunif(0, 5)\n }\n for (k in 1:Ncovariate) {\n gamma[1, k] <- 0\n for (m in 2:Ntreat) {\n gamma[m, k] ~ ddexp(0, tt[m])\n }\n }\n}\n<environment: 0x55f006fab7a0>\n\nsamples <- ipd.run(ipd3, n.chains = 2, n.iter = 20, \n pars.save = c(\"alpha\", \"beta\", \"delta\", \"sd\", \"gamma\"))\n\nCompiling model graph\n Resolving undeclared variables\n Allocating nodes\nGraph information:\n Observed stochastic nodes: 1000\n Unobserved stochastic nodes: 35\n Total graph size: 10141\n\nInitializing model\n\nsummary(samples)\n\n\nIterations = 2001:2020\nThinning interval = 1 \nNumber of chains = 2 \nSample size per chain = 20 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\nalpha[1] 10.94462 0.03642 0.005758 0.007510\nalpha[2] 8.02987 0.05584 0.008830 0.006986\nalpha[3] 10.52140 0.05249 0.008300 0.007490\nalpha[4] 9.59742 0.03939 0.006229 0.005516\nalpha[5] 12.98910 0.04428 0.007001 0.009043\nalpha[6] 13.17357 0.04200 0.006641 0.012095\nalpha[7] 7.35807 0.05812 0.009190 0.007383\nalpha[8] 11.09433 0.04855 0.007677 0.012594\nalpha[9] 10.12414 0.04685 0.007407 0.006077\nalpha[10] 9.23874 0.04361 0.006896 0.013196\nbeta[1] 0.19138 0.01698 0.002685 0.003651\nbeta[2] 0.30220 0.02002 0.003166 0.004782\ndelta[1] 0.00000 0.00000 0.000000 0.000000\ndelta[2] -3.03643 0.03470 0.005487 0.011251\ndelta[3] -1.23633 0.04148 0.006558 0.006838\ngamma[1,1] 0.00000 0.00000 0.000000 0.000000\ngamma[2,1] -0.61237 0.02441 0.003859 0.004079\ngamma[3,1] -0.34731 0.02765 0.004371 0.005636\ngamma[1,2] 0.00000 0.00000 0.000000 0.000000\ngamma[2,2] 0.58185 0.03100 0.004901 0.009026\ngamma[3,2] 0.42554 0.02697 0.004265 0.005172\nsd 0.06913 0.05598 0.008850 0.007766\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\nalpha[1] 10.875908 10.92211 10.9475 10.9751 10.9946\nalpha[2] 7.931808 7.99402 8.0203 8.0663 8.1354\nalpha[3] 10.429312 10.49357 10.5260 10.5596 10.5969\nalpha[4] 9.540423 9.56995 9.5937 9.6241 9.6622\nalpha[5] 12.907860 12.97286 12.9846 13.0158 13.0753\nalpha[6] 13.096715 13.14635 13.1720 13.2066 13.2449\nalpha[7] 7.251988 7.30633 7.3608 7.3976 7.4466\nalpha[8] 11.012250 11.06480 11.0897 11.1216 11.1917\nalpha[9] 10.051419 10.09225 10.1235 10.1512 10.2105\nalpha[10] 9.169217 9.21229 9.2374 9.2677 9.3169\nbeta[1] 0.159873 0.18048 0.1935 0.2020 0.2207\nbeta[2] 0.267644 0.29070 0.2992 0.3130 0.3490\ndelta[1] 0.000000 0.00000 0.0000 0.0000 0.0000\ndelta[2] -3.098316 -3.05326 -3.0418 -3.0307 -2.9669\ndelta[3] -1.317718 -1.24606 -1.2350 -1.2225 -1.1657\ngamma[1,1] 0.000000 0.00000 0.0000 0.0000 0.0000\ngamma[2,1] -0.665029 -0.62873 -0.6114 -0.5954 -0.5733\ngamma[3,1] -0.395346 -0.36931 -0.3508 -0.3252 -0.2958\ngamma[1,2] 0.000000 0.00000 0.0000 0.0000 0.0000\ngamma[2,2] 0.514378 0.55996 0.5898 0.6053 0.6207\ngamma[3,2] 0.376606 0.40579 0.4315 0.4447 0.4669\nsd 0.008162 0.01524 0.0579 0.1150 0.1807\n\n\nAs before, we can use the treatment.effect() function of bipd to estimate relative effects for new patients.\n\ntreatment.effect(ipd3, samples, newpatient= c(1,2))\n\n$`treatment 2`\n 0.025 0.5 0.975 \n-2.605809 -2.444450 -2.295272 \n\n$`treatment 3`\n 0.025 0.5 0.975 \n-0.8007046 -0.7261727 -0.5757139 \n\n\nThis gives us the relative effects for all treatments versus the reference. To obtain relative effects between active treatments we need some more coding:\n\nsamples.all=data.frame(rbind(samples[[1]], samples[[2]]))\nnewpatient= c(1,2)\nnewpatient <- (newpatient - ipd3$scale_mean)/ipd3$scale_sd\n\nmedian(\n samples.all$delta.2.+samples.all$gamma.2.1.*\n newpatient[1]+samples.all$gamma.2.2.*newpatient[2]\n-\n (samples.all$delta.3.+samples.all$gamma.3.1.*newpatient[1]+\n samples.all$gamma.3.2.*newpatient[2])\n)\n\n[1] -1.724038\n\nquantile(samples.all$delta.2.+samples.all$gamma.2.1.*\n newpatient[1]+samples.all$gamma.2.2.*newpatient[2]\n -(samples.all$delta.3.+samples.all$gamma.3.1.*newpatient[1]+\n samples.all$gamma.3.2.*newpatient[2])\n , probs = 0.025)\n\n 2.5% \n-1.876105 \n\nquantile(samples.all$delta.2.+samples.all$gamma.2.1.*\n newpatient[1]+samples.all$gamma.2.2.*newpatient[2]\n -(samples.all$delta.3.+samples.all$gamma.3.1.*newpatient[1]+\n samples.all$gamma.3.2.*newpatient[2])\n , probs = 0.975)\n\n 97.5% \n-1.619372 \n\n\n\n\n\n9.2.2 Modeling patient-level relative effects using randomized and observational evidence for a network of treatments\nWe will now follow Chapter 16.3.5 from the book. In this analysis we will not use penalization, and we will assume fixed effects. For an example with penalization and random effects, see part 2 of this vignettte.\n\n9.2.2.1 Setup\nWe generate a very simple dataset of three studies comparing three treatments. We will assume 2 RCTs and 1 non-randomized trial:\n\nds4 <- generate_ipdnma_example(type = \"continuous\")\nds4 <- ds4 %>% filter(studyid %in% c(1,4,10)) %>%\n mutate(studyid = factor(studyid) %>%\n recode_factor(\n \"1\" = \"1\",\n \"4\" = \"2\",\n \"10\" = \"3\"),\n design = ifelse(studyid == \"3\", \"nrs\", \"rct\"))\n\nThe sample size is as follows:\n\n\n \n s1 s2 s3\n treat A: 50 59 36\n treat B: 50 0 31\n treat C: 0 41 33\n\n\n\n\n9.2.2.2 Model fitting\nWe will use the design-adjusted model, equation 16.9 in the book. We will fit a two-stage fixed effects meta-analysis and we will use a variance inflation factor. The code below is used to specify the analysis of each individual study. Briefly, in each study we adjust the treatment effect for the prognostic factors z1 and z2, as well as their interaction with treat.\n\nlibrary(rjags)\n\nLoading required package: coda\n\n\nLinked to JAGS 4.3.0\n\n\nLoaded modules: basemod,bugs\n\nfirst.stage <- \"\nmodel{\n\nfor (i in 1:N){\n y[i] ~ dnorm(mu[i], tau) \n mu[i] <- a + inprod(b[], X[i,]) + inprod(c[,treat[i]], X[i,]) + d[treat[i]] \n}\nsigma ~ dunif(0, 5)\ntau <- pow(sigma, -2)\n\na ~ dnorm(0, 0.001)\n\nfor(k in 1:Ncovariate){\n b[k] ~ dnorm(0,0.001)\n}\n\nfor(k in 1:Ncovariate){\n c[k,1] <- 0\n}\n\ntauGamma <- pow(sdGamma,-1)\nsdGamma ~ dunif(0, 5)\n\nfor(k in 1:Ncovariate){\n for(t in 2:Ntreat){\n c[k,t] ~ ddexp(0, tauGamma)\n }\n}\n\nd[1] <- 0\nfor(t in 2:Ntreat){\n d[t] ~ dnorm(0, 0.001)\n}\n}\"\n\nSubsequently, we estimate the relative treatment effects in the first (randomized) study comparing treatments A and B:\n\nmodel1.spec <- textConnection(first.stage) \ndata1 <- with(ds4 %>% filter(studyid == 1), \n list(y = y,\n N = length(y), \n X = cbind(z1,z2), \n treat = treat,\n Ncovariate = 2, \n Ntreat = 2))\njags.m <- jags.model(model1.spec, data = data1, n.chains = 2, n.adapt = 500,\n quiet = TRUE)\nparams <- c(\"d\", \"c\") \nsamps4.1 <- coda.samples(jags.m, params, n.iter = 50)\nsamps.all.s1 <- data.frame(as.matrix(samps4.1))\n\nsamps.all.s1 <- samps.all.s1[, c(\"c.1.2.\", \"c.2.2.\", \"d.2.\")]\ndelta.1 <- colMeans(samps.all.s1)\ncov.1 <- var(samps.all.s1)\n\nWe repeat the analysis for the second (randomized) study comparing treatments A and C:\n\nmodel1.spec <- textConnection(first.stage) \ndata2 <- with(ds4 %>% filter(studyid == 2), \n list(y = y,\n N = length(y), \n X = cbind(z1,z2), \n treat = ifelse(treat == 3, 2, treat),\n Ncovariate = 2, \n Ntreat = 2))\njags.m <- jags.model(model1.spec, data = data2, n.chains = 2, n.adapt = 100,\n quiet = TRUE)\nparams <- c(\"d\", \"c\") \nsamps4.2 <- coda.samples(jags.m, params, n.iter = 50)\nsamps.all.s2 <- data.frame(as.matrix(samps4.2))\nsamps.all.s2 <- samps.all.s2[, c(\"c.1.2.\", \"c.2.2.\", \"d.2.\")]\ndelta.2 <- colMeans(samps.all.s2)\ncov.2 <- var(samps.all.s2)\n\nFinally, we analyze the third (non-randomized) study comparing treatments A, B, and C:\n\nmodel1.spec <- textConnection(first.stage) \ndata3 <- with(ds4 %>% filter(studyid == 3), \n list(y = y,\n N = length(y), \n X = cbind(z1,z2), \n treat = treat,\n Ncovariate = 2, \n Ntreat = 3))\njags.m <- jags.model(model1.spec, data = data3, n.chains = 2, n.adapt = 100,\n quiet = TRUE)\nparams <- c(\"d\", \"c\") \nsamps4.3 <- coda.samples(jags.m, params, n.iter = 50)\nsamps.all.s3 <- data.frame(as.matrix(samps4.3))\n\nsamps.all.s3 <- samps.all.s3[, c(\"c.1.2.\", \"c.2.2.\", \"d.2.\", \"c.1.3.\", \n \"c.2.3.\", \"d.3.\")]\ndelta.3 <- colMeans(samps.all.s3)\ncov.3 <- var(samps.all.s3)\n\nThe corresponding treatment effect estimates are depicted below:\n\n\n\n\nTable 9.4: Treatment effect estimates.\n\n\nstudy\nB versus A\nC versus A\n\n\n\n\nstudy 1\n-3.017 (SE = 0.055 )\n\n\n\nstudy 2\n\n-1.168 (SE = 0.060 )\n\n\nstudy 3\n-2.975 (SE = 0.071 )\n-0.927 (SE = 0.067 )\n\n\n\n\n\n\n\n\nWe can now fit the second stage of the network meta-analysis. The corresponding JAGS model is specified below:\n\nsecond.stage <-\n\"model{\n \n #likelihood\n y1 ~ dmnorm(Mu1, Omega1)\n y2 ~ dmnorm(Mu2, Omega2)\n y3 ~ dmnorm(Mu3, Omega3*W)\n\n \n Omega1 <- inverse(cov.1)\n Omega2 <- inverse(cov.2)\n Omega3 <- inverse(cov.3)\n\n Mu1 <- c(gamma[,1], delta[2])\n Mu2 <- c(gamma[,2], delta[3]) \n Mu3 <- c(gamma[,1], delta[2],gamma[,2], delta[3])\n \n #parameters\n for(i in 1:2){\n gamma[i,1] ~ dnorm(0, 0.001)\n gamma[i,2] ~ dnorm(0, 0.001)\n }\n \n delta[1] <- 0\n delta[2] ~ dnorm(0, 0.001)\n delta[3] ~ dnorm(0, 0.001)\n \n}\n\"\n\nWe can fit as follows:\n\nmodel1.spec <- textConnection(second.stage) \ndata3 <- list(y1 = delta.1, y2 = delta.2, y3 = delta.3, \n cov.1 = cov.1, cov.2 = cov.2, cov.3 = cov.3, W = 0.5)\n\njags.m <- jags.model(model1.spec, data = data3, n.chains = 2, n.adapt = 50,\n quiet = TRUE)\nparams <- c(\"delta\", \"gamma\") \nsamps4.3 <- coda.samples(jags.m, params, n.iter = 50)\n\n\nsummary(samps4.3)\n\n\nIterations = 1:50\nThinning interval = 1 \nNumber of chains = 2 \nSample size per chain = 50 \n\n1. Empirical mean and standard deviation for each variable,\n plus standard error of the mean:\n\n Mean SD Naive SE Time-series SE\ndelta[1] 0.0000 0.00000 0.000000 0.000000\ndelta[2] -3.0202 0.05245 0.005245 0.005270\ndelta[3] -1.1223 0.04805 0.004805 0.004997\ngamma[1,1] -0.9069 0.05836 0.005836 0.005842\ngamma[2,1] 0.8249 0.10712 0.010712 0.012136\ngamma[1,2] -0.6237 0.05104 0.005104 0.005031\ngamma[2,2] 0.3478 0.04333 0.004333 0.004583\n\n2. Quantiles for each variable:\n\n 2.5% 25% 50% 75% 97.5%\ndelta[1] 0.0000 0.0000 0.0000 0.0000 0.0000\ndelta[2] -3.1151 -3.0530 -3.0253 -2.9950 -2.9078\ndelta[3] -1.2100 -1.1513 -1.1256 -1.0911 -1.0281\ngamma[1,1] -1.0339 -0.9435 -0.9025 -0.8749 -0.8065\ngamma[2,1] 0.6784 0.7829 0.8197 0.8547 0.9202\ngamma[1,2] -0.7334 -0.6541 -0.6266 -0.5889 -0.5287\ngamma[2,2] 0.2701 0.3133 0.3487 0.3801 0.4227\n\n# calculate treatment effects\nsamples.all = data.frame(rbind(samps4.3[[1]], samps4.3[[2]]))\nnewpatient = c(1,2)\n\nmedian(\n samples.all$delta.2. + samples.all$gamma.1.1.*newpatient[1] +\n samples.all$gamma.2.1.*newpatient[2]\n)\n\n[1] -2.282333\n\nquantile(samples.all$delta.2.+samples.all$gamma.1.1.*newpatient[1]+\n samples.all$gamma.2.1.*newpatient[2]\n , probs = 0.025)\n\n 2.5% \n-2.640549 \n\nquantile(samples.all$delta.2.+samples.all$gamma.1.1.*newpatient[1]+\n samples.all$gamma.2.1.*newpatient[2]\n , probs = 0.975)\n\n 97.5% \n-2.014692" }, { "objectID": "chapter_16.html#version-info", @@ -354,7 +354,7 @@ "href": "chapter_18.html#introduction", "title": "10  Visualization and interpretation of individualized treatment rule results", "section": "10.1 Introduction", - "text": "10.1 Introduction\nWe first load all relevant functions for this chapter.\n\nsource(\"resources/chapter 18/functions.r\")\n\nInstalling package into '/home/runner/work/_temp/Library'\n(as 'lib' is unspecified)\n\n\nSubsequently, we use the function simcountdata() to generate an example dataset with a sample size of N=2000. In this example, we have two disease modifying therapies (DMT1 and DMT0) and the outcome is the number of post-treatment multiple sclerosis relapses during follow-up.\n\n# Randomization seed\nbase.seed <- 999\n\nset.seed(base.seed)\ndf.ori <- simcountdata(n = 2000,\n seed = 63,\n beta = c(log(0.4), log(0.5), log(1), log(1.1), log(1.2)),\n beta.x = c(-1.54, -0.01, 0.06, 0.25, 0.5, 0.13, 0.0000003)\n)$data\n\nThank you for using fastDummies!\n\n\nTo acknowledge our work, please cite the package:\n\n\nKaplan, J. & Schlegel, B. (2023). fastDummies: Fast Creation of Dummy (Binary) Columns and Rows from Categorical Variables. Version 1.7.1. URL: https://github.com/jacobkap/fastDummies, https://jacobkap.github.io/fastDummies/.\n\n\nThe dataset looks as follows:\n\nhead(df.ori)\n\n trt ageatindex_centered female prerelapse_num prevDMTefficacy premedicalcost\n1 0 2 0 2 Low efficacy 4606.04\n2 1 10 1 1 Low efficacy 17065.19\n3 1 12 1 2 None 6308.39\n4 1 -12 0 0 Low efficacy 16633.97\n5 1 13 1 0 Low efficacy 642.96\n6 1 14 1 0 Low efficacy 2989.89\n numSymptoms postrelapse_num finalpostdayscount group score Iscore\n1 0 1 305 Simulated 0.7129792 1\n2 1 0 367 Simulated 0.7404238 2\n3 0 0 325 Simulated 0.7564233 3\n4 0 0 321 Simulated 0.7215764 1\n5 0 0 24 Simulated 0.7457823 2\n6 0 0 59 Simulated 0.7441632 2\n\n\nBelow is a summary table of the baseline characteristics by treatment group.\n\n\n\n\n\nBaseline characteristics of the case study data\n\n\n\n\n\n\n\n\n\n0\n(N=506)\n1\n(N=1494)\nOverall\n(N=2000)\n\n\n\n\nAge (years)\n\n\n\n\n\nMean (SD)\n45.2 (9.82)\n45.8 (9.73)\n45.7 (9.75)\n\n\nMedian [Min, Max]\n46.0 [20.0, 64.0]\n46.0 [19.0, 64.0]\n46.0 [19.0, 64.0]\n\n\nGender\n\n\n\n\n\nfemale\n375 (74.1%)\n1123 (75.2%)\n1498 (74.9%)\n\n\nmale\n131 (25.9%)\n371 (24.8%)\n502 (25.1%)\n\n\nPrevious number of relapses\n\n\n\n\n\n0\n319 (63.0%)\n973 (65.1%)\n1292 (64.6%)\n\n\n1\n150 (29.6%)\n427 (28.6%)\n577 (28.9%)\n\n\n2\n31 (6.1%)\n76 (5.1%)\n107 (5.4%)\n\n\n3\n5 (1.0%)\n17 (1.1%)\n22 (1.1%)\n\n\n4\n1 (0.2%)\n1 (0.1%)\n2 (0.1%)\n\n\nEfficacy of previous disease modifying therapy\n\n\n\n\n\nLow efficacy\n216 (42.7%)\n609 (40.8%)\n825 (41.3%)\n\n\nMedium and high efficacy\n53 (10.5%)\n179 (12.0%)\n232 (11.6%)\n\n\nNone\n237 (46.8%)\n706 (47.3%)\n943 (47.2%)\n\n\nPrevious medical cost (\\$)\n\n\n\n\n\nMean (SD)\n13700 (20400)\n14400 (24500)\n14300 (23600)\n\n\nMedian [Min, Max]\n7320 [343, 264000]\n7560 [110, 556000]\n7470 [110, 556000]\n\n\nPrevious number of symptoms\n\n\n\n\n\n0\n348 (68.8%)\n995 (66.6%)\n1343 (67.2%)\n\n\n1\n119 (23.5%)\n388 (26.0%)\n507 (25.4%)\n\n\n>=2\n39 (7.7%)\n111 (7.4%)\n150 (7.5%)\n\n\n\n\n\n\n\nWe now define key constants for the case study.\n\n# Baseline characteristics\ncovars <- c(\"age.z\", \"female\", \"prevtrtB\", \"prevtrtC\", \"prevnumsymp1\", \n \"prevnumsymp2p\", \"previous_cost.z\", \"previous_number_relapses\")\n\n# Precision medicine methods to be used\npm.methods <- c(\"all1\", \"all0\", \"poisson\", \"dWOLS\", \"listDTR2\", \n \"contrastReg\")\n\n# Precision medicine method labels\nmethod.vec <- c(\"All 0\", \"All 1\", \"Poisson\", \"dWOLS\", \n \"Contrast\\n Regression\", \"List DTR\\n (2 branches)\")\n\n# Number of folds in each CV iteration\nn.fold <- 5\n\n# Number of CV iterations\nn.cv <- 10\n\n# Sample size of the large independent test set to get true value\nbig.n <- 100000\n\n# Define formula for the CATE model\ncate.formula <- as.formula(paste0(\"y ~\", paste0(covars, collapse = \"+\"), \n \"+ offset(log(years))\"))\n\n# Define formula for the propensity score model\nps.formula <- trt ~ age.z + prevtrtB + prevtrtC\n\n# Color\nmyblue <- rgb(37, 15, 186, maxColorValue = 255)\nmygreen <- rgb(109, 173, 70, maxColorValue = 255)\nmygrey <- rgb(124, 135, 142, maxColorValue = 255)\n\nThe data need to be preprocessed to be more analyzable. We recategorized treatment, previous treatment, and number of symptoms; scaled medical cost and age; and standardized the data.\n\ndf <- df.ori %>%\n rename(previous_treatment = prevDMTefficacy,\n age = ageatindex_centered,\n y = postrelapse_num,\n previous_number_relapses = prerelapse_num,\n previous_number_symptoms = numSymptoms,\n previous_cost = premedicalcost) %>%\n mutate(previous_treatment = factor(previous_treatment, \n levels = c(\"None\", \n \"Low efficacy\", \n \"Medium and high efficacy\"), \n labels = c(\"drugA\", \"drugB\", \"drugC\")),\n previous_number_symptoms = factor(previous_number_symptoms, \n levels = c(\"0\", \"1\", \">=2\"), \n labels = c(\"0\", \"1\", \">=2\")),\n trt = factor(trt, levels = c(0, 1), labels = c(\"drug0\", \"drug1\")),\n previous_cost.z = scale(log(previous_cost), scale = TRUE), \n age.z = age + 48,\n age.z = scale(age.z, scale = TRUE),\n years = finalpostdayscount / 365.25,\n mlogarr0001 = -log(y / years + 0.001),\n drug1 = as.numeric(trt == \"drug1\"),\n prevtrtB = as.numeric(previous_treatment == \"drugB\"),\n prevtrtC = as.numeric(previous_treatment == \"drugC\"),\n prevnumsymp1 = as.numeric(previous_number_symptoms == \"1\"),\n prevnumsymp2p = as.numeric(previous_number_symptoms == \">=2\")) %>%\n dplyr::select(age.z, female, contains(\"prevtrt\"), previous_cost.z, \n contains(\"prevnumsymp\"), \n previous_number_relapses, trt, drug1, y, \n mlogarr0001, years, Iscore)\n\n# Standardize data\nz.labels <- c(\"age.z\", \"previous_cost.z\")\ndf.s <- df\ndf.s[, setdiff(covars, z.labels)] <- df[, setdiff(covars, z.labels)]" + "text": "10.1 Introduction\nWe first load all relevant functions for this chapter.\n\nsource(\"resources/chapter 18/functions.r\")\n\nSubsequently, we use the function simcountdata() to generate an example dataset with a sample size of N=2000. In this example, we have two disease modifying therapies (DMT1 and DMT0) and the outcome is the number of post-treatment multiple sclerosis relapses during follow-up.\n\n# Randomization seed\nbase.seed <- 999\n\nset.seed(base.seed)\ndf.ori <- simcountdata(n = 2000,\n seed = 63,\n beta = c(log(0.4), log(0.5), log(1), log(1.1), log(1.2)),\n beta.x = c(-1.54, -0.01, 0.06, 0.25, 0.5, 0.13, 0.0000003)\n)$data\n\nThank you for using fastDummies!\n\n\nTo acknowledge our work, please cite the package:\n\n\nKaplan, J. & Schlegel, B. (2023). fastDummies: Fast Creation of Dummy (Binary) Columns and Rows from Categorical Variables. Version 1.7.1. URL: https://github.com/jacobkap/fastDummies, https://jacobkap.github.io/fastDummies/.\n\n\nThe dataset looks as follows:\n\nhead(df.ori)\n\n trt ageatindex_centered female prerelapse_num prevDMTefficacy premedicalcost\n1 0 2 0 2 Low efficacy 4606.04\n2 1 10 1 1 Low efficacy 17065.19\n3 1 12 1 2 None 6308.39\n4 1 -12 0 0 Low efficacy 16633.97\n5 1 13 1 0 Low efficacy 642.96\n6 1 14 1 0 Low efficacy 2989.89\n numSymptoms postrelapse_num finalpostdayscount group score Iscore\n1 0 1 305 Simulated 0.7129792 1\n2 1 0 367 Simulated 0.7404238 2\n3 0 0 325 Simulated 0.7564233 3\n4 0 0 321 Simulated 0.7215764 1\n5 0 0 24 Simulated 0.7457823 2\n6 0 0 59 Simulated 0.7441632 2\n\n\nBelow is a summary table of the baseline characteristics by treatment group.\n\n\n\n\n\nBaseline characteristics of the case study data\n\n\n\n\n\n\n\n\n\n0\n(N=506)\n1\n(N=1494)\nOverall\n(N=2000)\n\n\n\n\nAge (years)\n\n\n\n\n\nMean (SD)\n45.2 (9.82)\n45.8 (9.73)\n45.7 (9.75)\n\n\nMedian [Min, Max]\n46.0 [20.0, 64.0]\n46.0 [19.0, 64.0]\n46.0 [19.0, 64.0]\n\n\nGender\n\n\n\n\n\nfemale\n375 (74.1%)\n1123 (75.2%)\n1498 (74.9%)\n\n\nmale\n131 (25.9%)\n371 (24.8%)\n502 (25.1%)\n\n\nPrevious number of relapses\n\n\n\n\n\n0\n319 (63.0%)\n973 (65.1%)\n1292 (64.6%)\n\n\n1\n150 (29.6%)\n427 (28.6%)\n577 (28.9%)\n\n\n2\n31 (6.1%)\n76 (5.1%)\n107 (5.4%)\n\n\n3\n5 (1.0%)\n17 (1.1%)\n22 (1.1%)\n\n\n4\n1 (0.2%)\n1 (0.1%)\n2 (0.1%)\n\n\nEfficacy of previous disease modifying therapy\n\n\n\n\n\nLow efficacy\n216 (42.7%)\n609 (40.8%)\n825 (41.3%)\n\n\nMedium and high efficacy\n53 (10.5%)\n179 (12.0%)\n232 (11.6%)\n\n\nNone\n237 (46.8%)\n706 (47.3%)\n943 (47.2%)\n\n\nPrevious medical cost (\\$)\n\n\n\n\n\nMean (SD)\n13700 (20400)\n14400 (24500)\n14300 (23600)\n\n\nMedian [Min, Max]\n7320 [343, 264000]\n7560 [110, 556000]\n7470 [110, 556000]\n\n\nPrevious number of symptoms\n\n\n\n\n\n0\n348 (68.8%)\n995 (66.6%)\n1343 (67.2%)\n\n\n1\n119 (23.5%)\n388 (26.0%)\n507 (25.4%)\n\n\n>=2\n39 (7.7%)\n111 (7.4%)\n150 (7.5%)\n\n\n\n\n\n\n\nWe now define key constants for the case study.\n\n# Baseline characteristics\ncovars <- c(\"age.z\", \"female\", \"prevtrtB\", \"prevtrtC\", \"prevnumsymp1\", \n \"prevnumsymp2p\", \"previous_cost.z\", \"previous_number_relapses\")\n\n# Precision medicine methods to be used\npm.methods <- c(\"all1\", \"all0\", \"poisson\", \"dWOLS\", \"listDTR2\", \n \"contrastReg\")\n\n# Precision medicine method labels\nmethod.vec <- c(\"All 0\", \"All 1\", \"Poisson\", \"dWOLS\", \n \"Contrast\\n Regression\", \"List DTR\\n (2 branches)\")\n\n# Number of folds in each CV iteration\nn.fold <- 5\n\n# Number of CV iterations\nn.cv <- 10\n\n# Sample size of the large independent test set to get true value\nbig.n <- 100000\n\n# Define formula for the CATE model\ncate.formula <- as.formula(paste0(\"y ~\", paste0(covars, collapse = \"+\"), \n \"+ offset(log(years))\"))\n\n# Define formula for the propensity score model\nps.formula <- trt ~ age.z + prevtrtB + prevtrtC\n\n# Color\nmyblue <- rgb(37, 15, 186, maxColorValue = 255)\nmygreen <- rgb(109, 173, 70, maxColorValue = 255)\nmygrey <- rgb(124, 135, 142, maxColorValue = 255)\n\nThe data need to be preprocessed to be more analyzable. We recategorized treatment, previous treatment, and number of symptoms; scaled medical cost and age; and standardized the data.\n\ndf <- df.ori %>%\n rename(previous_treatment = prevDMTefficacy,\n age = ageatindex_centered,\n y = postrelapse_num,\n previous_number_relapses = prerelapse_num,\n previous_number_symptoms = numSymptoms,\n previous_cost = premedicalcost) %>%\n mutate(previous_treatment = factor(previous_treatment, \n levels = c(\"None\", \n \"Low efficacy\", \n \"Medium and high efficacy\"), \n labels = c(\"drugA\", \"drugB\", \"drugC\")),\n previous_number_symptoms = factor(previous_number_symptoms, \n levels = c(\"0\", \"1\", \">=2\"), \n labels = c(\"0\", \"1\", \">=2\")),\n trt = factor(trt, levels = c(0, 1), labels = c(\"drug0\", \"drug1\")),\n previous_cost.z = scale(log(previous_cost), scale = TRUE), \n age.z = age + 48,\n age.z = scale(age.z, scale = TRUE),\n years = finalpostdayscount / 365.25,\n mlogarr0001 = -log(y / years + 0.001),\n drug1 = as.numeric(trt == \"drug1\"),\n prevtrtB = as.numeric(previous_treatment == \"drugB\"),\n prevtrtC = as.numeric(previous_treatment == \"drugC\"),\n prevnumsymp1 = as.numeric(previous_number_symptoms == \"1\"),\n prevnumsymp2p = as.numeric(previous_number_symptoms == \">=2\")) %>%\n dplyr::select(age.z, female, contains(\"prevtrt\"), previous_cost.z, \n contains(\"prevnumsymp\"), \n previous_number_relapses, trt, drug1, y, \n mlogarr0001, years, Iscore)\n\n# Standardize data\nz.labels <- c(\"age.z\", \"previous_cost.z\")\ndf.s <- df\ndf.s[, setdiff(covars, z.labels)] <- df[, setdiff(covars, z.labels)]" }, { "objectID": "chapter_18.html#estmition-of-individualized-treatment-rules", @@ -403,6 +403,6 @@ "href": "authors.html", "title": "11  Book Authors", "section": "", - "text": "We gratefully acknowledge the contribution from the following authors:\n\nAuthors\n\n\n\n\n\n\nAuthor\nAffiliation\n\n\n\n\nAlf Scotland\nBiogen Digital Health International GmbH, Baar, Switzerland\n\n\nAmr Makady\nThe Janssen Pharmaceutical Companies of Johnson & Johnson, Breda, The Netherlands\n\n\nCarl de Moor\nCertara, Cambridge, MA, United States\n\n\nChangyu Shen\nBiogen, Cambridge, MA, United States\n\n\nChristina Read\nUtrecht University, Utrecht, The Netherlands\n\n\nChristine Fletcher\nGlaxoSmithKline, Stevenage, United Kingdom\n\n\nElvira D’Andrea\nAbbVie Inc., Boston, MA, United States\n\n\nFabio Pellegrini\nBiogen Spain, Madrid, Spain\n\n\nGabrielle Simoneau\nBiogen Canada, Toronto, Canada\n\n\nGerko Vink\nUtrecht University, Utrecht, The Netherlands\n\n\nGrammati Sarri\nCytel Inc., London, United Kingdom\n\n\nHanne Oberman\nUtrecht University, Utrecht, The Netherlands\n\n\nJamie Elvidge\nNational Institute for Health and Care Excellence (NICE), Manchester, United Kingdom\n\n\nJanie Coulombe\nUniversité de Montréal, Montréal, Canada\n\n\nJeremy Dietz\nNational Institute for Health and Care Excellence (NICE), London, United Kingdom\n\n\nJohanna Muñoz\nJulius Center for Health Sciences and Primary Care, University Medical Center Utrecht, Utrecht University, Utrecht, The Netherlands\n\n\nKatrine Strandberg-Larsen\nDepartment of Public Health, University of Copenhagen, Copenhagen, Denmark\n\n\nKonstantina Chalkou\nInstitute of Social and Preventive Medicine (ISPM), University of Bern, Bern, Switzerland\n\n\nMohammad Ehsanul Karim\nSchool of Population and Public Health, University of British Columbia, Vancouver, Canada\n\n\nTammy Jiang\nBiogen, Cambridge, MA, United States" + "text": "We gratefully acknowledge the contribution from the following authors:\n\nAuthors\n\n\n\n\n\n\nAuthor\nAffiliation\n\n\n\n\nAlf Scotland\nBiogen Digital Health International GmbH, Baar, Switzerland\n\n\nAmr Makady\nThe Janssen Pharmaceutical Companies of Johnson & Johnson, Breda, The Netherlands\n\n\nCarl de Moor\nCertara, Cambridge, MA, United States\n\n\nChangyu Shen\nBiogen, Cambridge, MA, United States\n\n\nChristina Read\nUtrecht University, Utrecht, The Netherlands\n\n\nChristine Fletcher\nGlaxoSmithKline, Stevenage, United Kingdom\n\n\nElvira D’Andrea\nAbbVie Inc., Boston, MA, United States\n\n\nFabio Pellegrini\nBiogen Spain, Madrid, Spain\n\n\nGabrielle Simoneau\nBiogen Canada, Toronto, Canada\n\n\nGerko Vink\nUtrecht University, Utrecht, The Netherlands\n\n\nGrammati Sarri\nCytel Inc., London, United Kingdom\n\n\nHanne Oberman\nUtrecht University, Utrecht, The Netherlands\n\n\nJamie Elvidge\nNational Institute for Health and Care Excellence (NICE), Manchester, United Kingdom\n\n\nJanie Coulombe\nUniversité de Montréal, Montréal, Canada\n\n\nJeremy Dietz\nNational Institute for Health and Care Excellence (NICE), London, United Kingdom\n\n\nJessica L. Rohmann\nCharité, Universitätsmedizin Berlin, Berlin, Germany\n\n\nJohanna Muñoz\nJulius Center for Health Sciences and Primary Care, University Medical Center Utrecht, Utrecht University, Utrecht, The Netherlands\n\n\nKatrine Strandberg-Larsen\nDepartment of Public Health, University of Copenhagen, Copenhagen, Denmark\n\n\nKonstantina Chalkou\nInstitute of Social and Preventive Medicine (ISPM), University of Bern, Bern, Switzerland\n\n\nMohammad Ehsanul Karim\nSchool of Population and Public Health, University of British Columbia, Vancouver, Canada\n\n\nTammy Jiang\nBiogen, Cambridge, MA, United States\n\n\nTat Thang Vo\nThe Wharton School, The University of Pennsylvania, Philadelphia, Pennsylvania, United States" } ] \ No newline at end of file

source("resources/chapter 18/functions.r")
-
-
Installing package into '/home/runner/work/_temp/Library'
-(as 'lib' is unspecified)
-