GithubHelp home page GithubHelp logo

joernge / lc-repeated-tests Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ekasb/lc-repeated-tests

1.0 0.0 0.0 535 KB

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: GNU General Public License v3.0

R 100.00%

lc-repeated-tests's Introduction

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

lc-repeated-tests's People

Contributors

ekasb avatar

Stargazers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.