Introduction

simKAP is an R package to simulate the kidney alocation process to get realistic recipient-donor pairs take into consideration of human intervention and dynamic waiting list modeling.
This vignette will walk through the implementation of this process using Australia recipient waiting list, Australia transplantation data and under Australia kidney allocation algorithm. With this demonstration using working exmaple, you will be able to customise your allocation process with modified functions such as a new National allocation (see section Customisable allocation process)

Loading Packages and Data

First, load simKAP via install simKAP.

We also load other packages for this vignette.

Then, we load the example data sampled from Australia kidney allocation database.

library(simKAP)
data("rawdata")
data("newdata")
recip_sample_list = readRDS("recip_sample_list.rds")
raw_donor_matrix$donor_rank = rank(raw_donor_matrix[,'donor_kdri']) / nrow(raw_donor_matrix)

Notice here, the features required from the historical transplant data are listed below:

Allocation process under Australia kidney allocation algorithm

The process is implemented through one huge function named runSimulation5.4 which calls dependent functions inside itself. This below example shows how to use this function and details about each argument are illustrated.

# example allocation process
result = simKAP::run_simulation(recip_sample_list[[1]], 
                                raw_donor_matrix,
                                algorithm_FUN = simKAP::allocation_national,
                                eligible_FUN = simKAP::selection_default,
                                matching_FUN = simKAP::dm_national_formula,
                                waitlist_FUN = simKAP::dynamic_waitlist,
                                state_algorithm = TRUE,
                                national_algorithm_threshold = 54000000,
                                state_algorithm_FUN = simKAP::australia_state_algorithm,
                                state_eligible_FUN = simKAP::australia_state_selection,
                                state_matching_FUN = simKAP::dm_state_formula,
                                eligible_arg = list(AB_priority = TRUE),
                                waitlist_arg = list(waitlist_Risk = FALSE),
                                resampleN = 1,
                                verbose = FALSE,
                                num_donor = 800,num_recip = 300,
                                state_balance = TRUE,
                                dynamic_waitlist = TRUE, 
                                National_II = TRUE,
                                is_parallel=FALSE,
                                ncores = 10)
saveRDS(result,"simKAP_eval.rds")
  1. recip_sample_list is a list of length 10 with 10 different samples contains recipient features, we take one sample from it to be used as our recipient matrix.
length(recip_sample_list)
#> [1] 10
head(recip_sample_list[[1]])
#>       recip_id recip_graftno recip_pra recip_blgroup recip_a1 recip_a2 recip_b1
#> 324 P8012631_1             1         0             A        1        2        8
#> 167 P7561113_1             1         0             A       30       32        7
#> 129 P7159736_1             1         0             A        2       24       18
#> 418 P9754808_1             1         2             A        1        2        8
#> 471 P9855484_1             1         6             A        2        3        7
#> 299 P7986678_1             1         1             A       11       24       62
#>     recip_b2 recip_dr1 recip_dr2 recip_dq1 recip_dq2 recip_state_initial
#> 324       50         3         7        NA        NA                 NSW
#> 167        8         8        11         2         7                 NSW
#> 129       44         7        11         2         7                 NSW
#> 418       51         3         8        NA        NA                 NSW
#> 471       51        14        15        NA        NA                 NSW
#> 299       75        15        15        NA         5                 NSW
#>     recip_state_current recip_age_rrtstart recip_sex
#> 324                 NSW                 43         F
#> 167                 NSW                 50         M
#> 129                 NSW                 14         F
#> 418                 NSW                 24         M
#> 471                 NSW                 21         M
#> 299                 NSW                 51         F
#>                   recip_eth_detailed recip_eth
#> 324                        Caucasoid      <NA>
#> 167    Sub-Saharan African (Specify)   AFRICAN
#> 129 Oceanian - Australian Aboriginal      <NA>
#> 418                        Caucasoid      <NA>
#> 471                        Caucasoid      <NA>
#> 299      South-East Asian - Filipino      <NA>
#>                                recip_primrenal recip_biopsy recip_creatinine
#> 324            Familial GN (Including Alports)            Y              981
#> 167                        Uncertain Diagnosis            Y              944
#> 129                   Medullary Cystic Disease            N             1847
#> 418                            Other (Specify)            N              680
#> 471 Focal Sclerosing GN (Including Hyalinosis)            Y              992
#> 299             Mesangial Proliferative (Iga+)            Y              647
#>     recip_height recip_weight recip_smoker recip_rrtstartdate recip_deathdate
#> 324        166.0         78.8       Former         2009-08-31            <NA>
#> 167        169.0         81.7        Never         2014-02-07            <NA>
#> 129        146.3         35.0        Never         2016-03-18            <NA>
#> 418        187.0         62.0        Never         2004-03-09            <NA>
#> 471        166.0         44.0       Former         2000-09-14            <NA>
#> 299        150.0         47.7        Never         2010-07-24            <NA>
#>     recip_state recip_age recip_waittime recip_lung recip_coronary recip_pvd
#> 324         NSW        49           2230          N              N         N
#> 167         NSW        54           1135          N              Y         N
#> 129         NSW        15            414          N              N         N
#> 418         NSW        32           2969          N              Y         S
#> 471         NSW        29           2981          N              N         N
#> 299         NSW        56           1784          N              Y         N
#>     recip_cvd recip_diabetes recip_comorb_date recip_cancer recip_liststartdate
#> 324         S              N        2014-12-31           No          2015-09-28
#> 167         N              N        2016-12-31           No          2016-09-27
#> 129         N              N        2016-12-31           No          2016-12-06
#> 418         N              N        2011-12-31          Yes          2011-01-25
#> 471         N              N        2007-12-31           No          2006-06-28
#> 299         N              N        2014-12-31           No          2011-10-14
#>     recip_waitstatus recip_listtime  recip_epts riskscore recip_algorithm
#> 324           Active             11 1.508669665  428.1523           State
#> 167           Active            172 1.571033572  519.4296           State
#> 129           Active            151 0.001691208  584.8409           State
#> 418           Active            456 0.788597613  370.9716           State
#> 471           Active            868 0.648729266  428.3344           State
#> 299           Active           1337 1.778272034  417.9297           State
#>     recip_id_original recip_original_listdate recip_original_rrtstartdate
#> 324          P8012631              2015-09-28                  2009-08-31
#> 167          P7561113              2016-09-27                  2014-02-07
#> 129          P7159736              2016-12-06                  2016-03-18
#> 418          P9754808              2011-01-25                  2004-03-09
#> 471          P9855484              2006-06-28                  2000-09-14
#> 299          P7986678              2011-10-14                  2010-07-24
#>     recip_tx_date recip_birthdate pra_group recip_age_group
#> 324    2015-10-09      1966-10-09    [0,20)         [45,55)
#> 167    2017-03-18      1963-03-18    [0,20)         [45,55)
#> 129    2017-05-06      2002-05-06    [0,20)          [0,45)
#> 418    2012-04-25      1980-04-25    [0,20)          [0,45)
#> 471    2008-11-12      1979-11-12    [0,20)          [0,45)
#> 299    2015-06-12      1959-06-12    [0,20)         [55,65)
dim(recip_sample_list[[1]])
#> [1] 1483   49
  1. raw_donor_matrix is a donor matrix contains donor features
head(raw_donor_matrix)
#>   donor_source donor_state donor_blgroup donor_a1 donor_a2 donor_b1 donor_b2
#> 1     Deceased         QLD             O        1       25        8       27
#> 2     Deceased         NSW             A       23       68       44       44
#> 3     Deceased         QLD             O        2       68       57       60
#> 4     Deceased         QLD             B       11       34        8       18
#> 5     Deceased         QLD             A        1        3        7        8
#> 6     Deceased         QLD             O        1       68        8       35
#>   donor_dr1 donor_dr2 donor_dq1 donor_dq2 donor_height donor_weight
#> 1        15        17         2         6          175           75
#> 2         4        15         6         8          173           80
#> 3         4         9         7         9          170           70
#> 4         7        13         2         6          169           87
#> 5        15        17         2         6          168           50
#> 6         3         7        NA         2          167           70
#>          donor_eth_code donor_eth_country donor_eth donor_diabetes
#> 1 Oceanian - Australian              <NA> Caucasian    No Diabetes
#> 2 Oceanian - Australian              <NA> Caucasian    No Diabetes
#> 3 Oceanian - Australian              <NA> Caucasian    No Diabetes
#> 4 Oceanian - Australian              <NA> Caucasian    No Diabetes
#> 5 Oceanian - Australian              <NA> Caucasian    No Diabetes
#> 6 Oceanian - Australian              <NA> Caucasian    No Diabetes
#>   donor_hypertension donor_smoker donor_id                  donor_death
#> 1                 No      Current  D988290       Traumatic Brain Injury
#> 2                 No       Former  D988863 Cerebral Hypoxia / Ischaemia
#> 3                 No        Never  D991428       Traumatic Brain Injury
#> 4                 No      Current  D843391 Cerebral Hypoxia / Ischaemia
#> 5                 No        Never  D990169 Cerebral Hypoxia / Ischaemia
#> 6                 No      Current D1006042     Intracranial Haemorrhage
#>   donor_dcd donor_creatinine donor_age donor_sex donor_kdri    tx_date
#> 1         N               53        39         M  1.0291885 2017-03-02
#> 2         Y              259        44         M  1.1770381 2016-12-26
#> 3         Y              199        17         M  0.8896358 2016-09-30
#> 4         Y               72        45         M  1.0281746 2017-11-17
#> 5         Y               76        17         F  0.8375934 2016-11-28
#> 6         Y               31        51         F  1.1623594 2016-01-14
#>   num_kidney donor_rank
#> 1          2 0.26067019
#> 2          1 0.39894180
#> 3          2 0.14038801
#> 4          2 0.25820106
#> 5          2 0.09664903
#> 6          2 0.38765432
dim(raw_donor_matrix)
#> [1] 2835   29
  1. algorithm_FUN and state_algorithm_FUN implement the Australia national and state allocation algorithms, notice here if you have your own algorithm, you can change this to your function name.

  2. eligible_FUN gives options to customise the eligible recipient pool, which means if you want to have a different pool with further restriction on eligible recipients, you can change it here.

This gives us a list of length 4 as the output (notice that you can take our saved result to have a look) and based on this list, you can analyse and demonstrate with your own preference.

The first one is the matched recipients and donors dataset with all recipient features, donor features and transplant matchability features. The second one is all those disgarded donor kidneys with the associated donor kidney features. The third one contains all those different donor-recipient state kidneys, i.e. those kidneys to achieve state balance. The last one is the dynamic waiting list results (corresponding to each recipient in the first full dataset)

simKAP_eval = readRDS("simKAP_eval.rds")
length(simKAP_eval)
#> [1] 4
dim(simKAP_eval[[1]])
#> [1] 1208   85
dim(simKAP_eval[[2]])
#> [1] 74 29
dim(simKAP_eval[[3]])
#> [1] 65 32
dim(simKAP_eval[[4]])
#> [1] 799   7

Customisable allocation process

This example simulation process shows the paried result under the CORisk allocation algorithm with a threshold number 0.2 introduced in our paper. Detailed main changes for this new algorithm compared with the above one are: eligible_FUN, matching_FUN, state_matching_FUN, waitlist_FUN. With no specification of matching_FUN, state_matching_FUN, waitlist_FUN, the dynamic waiting list and share decision making procedures are not implemented in this new algorithm. The threshold number is specified through the eligible_arg argument using threshold_number=0.2.

result_new = simKAP::run_simulation(recip_sample_list[[1]], 
                                    raw_donor_matrix,
                                    algorithm_FUN = allocation_national,
                                    eligible_FUN = selection_corisk,
                                    matching_FUN = select_max,
                                    state_algorithm = TRUE,
                                    national_algorithm_threshold = 54000000,
                                    state_algorithm_FUN = australia_state_algorithm,
                                    state_eligible_FUN = australia_state_selection,
                                    state_matching_FUN = select_max,
                                    eligible_arg = list(AB_priority = TRUE,threshold_number=0.2),
                                    resampleN = 1,
                                    verbose = FALSE,
                                    num_donor = 800,num_recip = 300,
                                    state_balance = TRUE,
                                    dynamic_waitlist = FALSE, 
                                    National_II = TRUE )
saveRDS(result_new,"us0.2full.rds")

This gives us a list of length 3 as the output (notice that you can take our saved result to have a look) and based on this list, you can analyse and demonstrate with your own preference.

The first one is the matched recipients and donors dataset with all recipient features, donor features and transplant matchability features. The second one is all those discarded donor kidneys with the associated donor kidney features. The third one is

us0.2 = readRDS("us0.2full.rds")
length(us0.2)
#> [1] 3
dim(us0.2[[1]])
#> [1] 1152   84
dim(us0.2[[2]])
#> [1] 96 29
dim(us0.2[[3]])
#> [1] 91 32

Session Info

sessionInfo("simKAP")
#> R version 4.1.1 (2021-08-10)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Catalina 10.15.7
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib
#> 
#> locale:
#> [1] en_AU.UTF-8/en_AU.UTF-8/en_AU.UTF-8/C/en_AU.UTF-8/en_AU.UTF-8
#> 
#> attached base packages:
#> character(0)
#> 
#> other attached packages:
#> [1] simKAP_0.1.0
#> 
#> loaded via a namespace (and not attached):
#>  [1] Rcpp_1.0.7        knitr_1.33        magrittr_2.0.1    grDevices_4.1.1  
#>  [5] R6_2.5.0          ragg_1.1.3        rlang_0.4.11      foreach_1.5.1    
#>  [9] fastmap_1.1.0     stringr_1.4.0     tools_4.1.1       utils_4.1.1      
#> [13] parallel_4.1.1    DT_0.18           xfun_0.25         snow_0.4-3       
#> [17] jquerylib_0.1.4   crosstalk_1.1.1   iterators_1.0.13  htmltools_0.5.1.1
#> [21] stats_4.1.1       systemfonts_1.0.2 datasets_4.1.1    yaml_2.2.1       
#> [25] digest_0.6.27     rprojroot_2.0.2   base_4.1.1        pkgdown_1.6.1    
#> [29] crayon_1.4.1      doSNOW_1.0.19     textshaping_0.3.5 codetools_0.2-18 
#> [33] sass_0.4.0        htmlwidgets_1.5.3 graphics_4.1.1    fs_1.5.0         
#> [37] memoise_2.0.0     cachem_1.0.5      evaluate_0.14     rmarkdown_2.10   
#> [41] stringi_1.7.3     compiler_4.1.1    bslib_0.2.5.1     generics_0.1.0   
#> [45] methods_4.1.1     desc_1.3.0        lubridate_1.7.10  jsonlite_1.7.2