Skip to content

latent class model for repeated binary tests (Wang & Hanson, 2019) in JAGS for R, related publication: Wichert et al. "Detection of low MAP shedder prevalence in large free-stall dairy herds by repeated testing of environmental samples and pooled milk samples" (https://doi.org/10.3390/ani12111343)

License

Notifications You must be signed in to change notification settings

ekasb/lc-repeated-tests

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About this repository

This repository contains an R script for a latent class model to estimate sensitivity and specificity of multiple repeated diagnostic tests, as it was used for the publication by Wichert et al. "Detection of low MAP shedder prevalence in large free-stall dairy herds by repeated testing of environmental samples and pooled milk samples" (doi: 10.3390/ani12111343). The R script contains a JAGS model, which can be run in R via runjags or rjags, for example.

About the model

This latent class model was proposed by Wang and Hanson in 2019 to estimate sensitivity and specificity of multiple diagnostic tests, which are applied repeatedly to the same subjects, if a gold standard is not or only partially available (doi: 10.1002/sim.8114).

Our implementation builds on code for a related model without repeated measurements (Wang, Lin & Nelson 2020, doi: 10.1177/0962280219852649, model M2). We adapted the code to repeated tests in accordance with the definition by Wang & Hanson (2019). To estimate sensitivity and specificity of test combinations, we further expanded the model to parallel testing, as described in Wang & Hanson (2019).

Parallel testing means that multiple tests are applied to the same subject and if at least one test gives a positive result, the parallel test is evaluated as positive. Thus, for a negative result of a parallel test, all included tests have to be negative. Such a combination of test results can include multiple diagnostic tests and / or multiple time points. In our implementation, the number of time points included in a parallel test can not be specified, but our code returns the sensitivity and specificity of a parallel test for 1, 2, ..., J time points, with J being the maximum number of time points of the study. This behaviour was hard-coded for our purposes to inspect the diagnostic accuracy of parallel tests with increasing numbers of applications.

Usage and arguments

Download the R script jags_model_with_parallel_tests.R into your working directory and run it once in R to create repeated_measurements_parallel_tests.bug. This file is used as input for runjags or rjags.

The following arguments have to be specified in R:

K number of diagnostic tests
J number of time points
N number of subjects
x array of dimension N ⨯ K ⨯ J containing the binary test results (0: negative, 1: positive)
ref vector of length N indicating the true disease status of each subject (-1: unknown, 0: negative, 1: positive)
z vector of length N containing zeros (for Poisson zero trick)
ncomb number of test combinations to be considered for parallel testing
comb matrix of dimension ncomb ⨯ K. Each row codes a combination of the diagnostic tests using zeros for ‘not included’ and ones for ‘included’, e.g., if Test 1 and 3 out of three tests should be combined into a parallel test, this would be given as '1, 0, 1'.
z2 matrix of dimension ncomb ⨯ J containing zeros (Poisson zero trick for sensitivity of parallel tests)
z3 matrix of dimension ncomb ⨯ J containing zeros (Poisson zero trick for specificity of parallel tests)

For example, if a study comprised 50 participants with unknown disease status, which were tested at 10 time points using three diagnostic tests, and the diagnostic accuracy of repeated applications of Test 1 interpreted in parallel should be evaluated over time, the arguments could be specified in R in the following way:

comb_mat <- matrix(c(1, 0, 0), nrow = 1, ncol = 3)

list_data <- list("K" = 3,
                  "J" = 10,
                  "N" = 50,
                  "x" = data_array,
                  "ref" = rep(-1, 50),
                  "z" = rep(0, 50),
                  "ncomb" = nrow(comb_mat),
                  "comb" = comb_mat,
                  "z2" = matrix(0, nrow = nrow(comb_mat), ncol = 10),
                  "z3" = matrix(0, nrow = nrow(comb_mat), ncol = 10))

We assume here that the test results are stored in data_array. If parallel tests are not required, parameter ncomb can simply be set to zero to suppress calculations for parallel tests.

The following variables of our model may be included in the list of monitored variables:

se estimated sensitivity of each test (vector of length K)
sp estimated specificity of each test (vector of length K)
rp estimated correlation between repeated measurements in the diseased population for each test (vector of length K)
rn estimated correlation between repeated measurements in the non-diseased population for each test (vector of length K)
cop estimated pairwise correlation between tests in the diseased population (matrix of dimension K ⨯ K, here a strictly upper triangular matrix, i.e. values on the main diagonal and below are set to zero to omit duplications)
con estimated pairwise correlation between tests in the non-diseased population (matrix of dimension K ⨯ K, a strictly upper triangular matrix like cop)
pi estimated disease prevalence
prob ‘likelihood contribution’ of each subject (vector of length N)
omega1 mode of beta distribution of test sensitivities (see Wang, Lin & Nelson, 2020)
omega2 mode of beta distribution of test specificities (see Wang, Lin & Nelson, 2020)
kappa1 spread of beta distribution of test sensitivities (see Wang, Lin & Nelson, 2020)
kappa2 spread of beta distribution of test specificities (see Wang, Lin & Nelson, 2020)
par_se estimated sensitivity of each parallel test (matrix of dimension ncomb ⨯ J, first index: row index of parallel test in matrix comb, second index: number of repeated measurements included in the parallel test)
par_sp estimated specificity of each parallel test (matrix of dimension ncomb ⨯ J, see par_se)

For example, the model could be run using runjags like this:

library(runjags)

out <- run.jags(model = "repeated_measurements_parallel_tests.bug",
                data = list_data, 
                monitor = c("se", "sp", "kappa1", "kappa2", "omega1", "omega2", 
                            "rp", "rn", "cop", "con", "pi",
                            "par_se", "par_sp", "prob"),
                n.chains = 3)

- see the reference manual and vignettes for runjags (here) or rjags (here) for details on running JAGS models in R.

References

  • Wang C, Hanson TE. Estimation of sensitivity and specificity of multiple repeated binary tests without a gold standard. Statistics in Medicine. 2019;38:2381–2390. doi: 10.1002/sim.8114
  • Wang C, Lin X, Nelson KP. Bayesian hierarchical latent class models for estimating diagnostic accuracy. Statistical Methods in Medical Research. 2020;29(4):1112-1128. doi: 10.1177/0962280219852649
  • Denwood MJ. runjags: An R Package Providing Interface Utilities, Model Templates, Parallel Computing Methods and Additional Distributions for MCMC Models in JAGS. Journal of Statistical Software. 2016;71(9):1-25. doi: 10.18637/jss.v071.i09
  • Plummer M. rjags: Bayesian Graphical Models using MCMC. R package version 4-10. 2019. Available at: https://CRAN.R-project.org/package=rjags

About

latent class model for repeated binary tests (Wang & Hanson, 2019) in JAGS for R, related publication: Wichert et al. "Detection of low MAP shedder prevalence in large free-stall dairy herds by repeated testing of environmental samples and pooled milk samples" (https://doi.org/10.3390/ani12111343)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages