Sample size for demonstrating freedom using pooled testing
This utility calcuates the number of pools required to be tested to provide a desired probability of detecting disease herd-sensitivity at the specified design prevalence, for a large (infinite) population, using pooled testing and assuming a fixed pool size and a test of known and 100% specificity. These analyses are an adaptation of the method from Cowling et el. (1999) (Prev Vet Med, 39:211-225), assuming known test sensitivity, perfect test specificity and 1 or more pools positive to declare a population infected (i.e. to be recognised as free there must be zero positive pools).
Inputs are the pool size used, pool-level test sensitivity, desired herd-sensitivity and design (target) prevalence. Test sensitivity is measured at the pool level (i.e. the probability that a pool will test positively if it represents one or more infected animals).
No results
################################################################ # program to calculate confidence in disease freedom using pooled testing ################################################################ rm(list = ls()) test<- ifelse(length(commandArgs()) < 3, TRUE, FALSE) fpath<- ifelse(test, "webRootUrl", "rtoolsPath") # load header scripts source(paste(fpath, "R/epi_head.R", sep = "")) source(paste(fpath, "R/HTMLStream.R", sep = "")) source(paste(fpath, "R/epitools_functions.r", sep = "")) # extract command arguments a1<- type.convert(a0[8:12]) # cat(a1) # initialise variables pool.size<- a1[1] n.pools<- a1[2] Sens<- a1[3] conf<- a1[4] # upper confidence limit design.prev<- a1[5] digits<- 4 pool.sizes<- c(1, 2, 3, 4, 5, 10, 15, 20, 25, 30, 40, 50, 100) prev.levels<- c(design.prev, 0.005, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2) # table of inputs inputs<- array("", dim = c(length(a1)-1, 1)) inputs[, 1]<- a1[c(1, 3:length(a1))] rownames(inputs)<- c("Pool size", "Pool sensitivity", "Confidence level", "Design prevalence") sens.poolsize<- 0 sens.poolsize[1:length(pool.sizes)]<- Sens names(a1)<- c("Pool size", "Number of pools", "Sensitivity", "Confidence level", "Design prevalence") filename<- digest(Sys.time) graphfile<- paste(fpath, "tmp/", filename, ".png", sep="") sinkfile<- paste(fpath, "tmp/", filename, ".txt", sep="") sink(sinkfile) # popuulation sensitivity with pooled sampling sep.pooled<- function(r, k, pstar, pse, psp=1) { # r = number of pools sampled (scalar or vector) # k = pool size (constant) (scalar or vector) # pstar = design prevalence # pse = pool-level sensitivity # psp = pool-level specificity # value: returns list of 2 elements, vector of sep values and vector of spp values sep<- 1 - ((1 - (1 - pstar)^k)*(1 - pse) + (1 - pstar)^k * psp)^r spp<- psp^r return(list(sep=sep, spp=spp)) } # sample size for pooled testing for freedom n.pooled<- function(sep, k, pstar, pse, psp=1) { # sep = desired population sensitivity (scalar or vector) # k = pool size (constant) (scalar or vector) # pstar = design prevalence # pse = pool-level sensitivity # psp = pool-level specificity n<- log(1-sep)/log(((1 - (1 - pstar)^k)*(1 - pse) + (1 - pstar)^k * psp)) return(ceiling(n)) } # result1<- round(Prevalence(n.pools, pool.size, conf, Sens), digits) # result2<- round(optimise(Confidence, c(0, 1), maximum = FALSE, m=n.pools, k=pool.size, Sens=Sens, prev=design.prev)$minimum, digits) result3<- n.pooled(conf, pool.size, design.prev, Sens) sample.sizes<- array(0, dim = c(length(pool.sizes), 9)) for (i in 1:length(pool.sizes)) { sample.sizes[i,]<- n.pooled(conf, pool.sizes[i], prev.levels, Sens) } colnames(sample.sizes)<- paste("Prevalence = ", prev.levels, sep = "") rownames(sample.sizes)<- paste("Pool size = ", pool.sizes, sep = "") n.lines<- 8 # length(pool.sizes) # graph results Title<-c("Pooled testing for Demonstrating Disease Freedom") OpenGraphOutput(graphfile, pointsize = 12, ht = 6, wd = 8) line.colours<- c("darkblue", "red", "darkgreen", "magenta", "brown", "purple", "black", "blue", "darkred", "tan") plot(x = prev.levels[2:9], y = sample.sizes[1,2:9], type="n", ylab = "No. of pools", ylim = c(0, max(sample.sizes[], na.rm = TRUE)), xlim = c(0, 0.1), xlab="Prevalence", main=Title, col = line.colours[1]) for (i in 1:n.lines) { lines(x = prev.levels[2:9], y = sample.sizes[i, 2:9], type = "l", col = line.colours[i]) } legend.txt<- rownames(sample.sizes)[1:n.lines] legend(0.1, max(sample.sizes[], na.rm = TRUE), legend.txt, xjust = 1, yjust = 1, col = line.colours, lty = c(1, 1), plot = TRUE, cex = 0.7) CloseGraphOutput("R") sink() # write to html and file heading<- "Sample size to demonstrate freedom using pooled testing" subheadings<- "Sample sizes for varying prevalence and pool size" tmp.file<- paste(fpath, "tmp/", filename, sep = "") result.txt<- paste("For a pool size of ", pool.size, ", a minimum of ", result3, " pools must be tested to provide ", conf*100, "% probability of detecting a prevalence of ", design.prev, ".
", "The table and graph below show the number of pools required for various pool sizes to provide ", conf*100, "% confidence of detecting a prevalence of ", design.prev, " and assuming a test sensitivity of ", Sens, " for all pool sizes.
", sep = "") output<- html.output(heading, subheadings, inputs, results = list(sample.sizes), graphs = graphfile, graph.headings = "Plot of sample sizes", show.inputs = T, show.graphs = T, tmp.file, result.txt = result.txt) write.html(output, tmp.file) cat(output)