Calculate the required sample size and cut-point for testing to demonstrate population freedom from disease using imperfect tests an allowing for small populations.

This utility uses the methods described by:
Cameron and Baldock (1998): A new probability formula for surveys to substantiate freedom from disease. Prev. Vet. Med. 34:1-17 and
Cameron (1999): Survey Toolbox for Livestock Diseases - A practical manual and software package for active surveillance of livestock diseases in developing countries. Australian Centre for International Agricultural Research, Canberra, Australia.
These methods are also the same as those used in the FreeCalc Program.

Inputs include:

• Size of the population sampled;
• Test sensitivity and specificity;
• Design prevalence (the hypothetical prevalence to be detected). Design prevalence can be specified as either a fixed number of elements from the population or a proportion of the population;
• Type I (1 - population-sensitivity) and Type II (1 - population-specificity) error values for determining whether to accept/reject the null or alternative hypothesis;
• Calculation method: hypergeometric (for small populations), or simple binomial (for large populations);
• The population size threshold, above which the simple binomial method is used regardless of which calculation method has been selected;
• The maximum upper limit for required sample size; and
• The desired precision of results (number of digits to be displayed after the decimal point).

The results are presented as:

• The minimum sample size and corresponding cut-point number of positives to achieve the specified type I and type II errors for the given population, design prevalence and test performance;
• achieved type I and Type II error levels and corresponding population-level sensitivities and specificities;
• A descriptive interpretation of the results; and
• an error message if the desired error levels cannot be achieved within the limits of populatuon and/or maximum sample size.

No example available
No references available
```				######################################
# Program to do freecalc calculations  for sample size
######################################
# uses RSurveillance package

x<- 1
rm(list = ls())
test<- ifelse(length(commandArgs()) == 2, TRUE, FALSE)
fpath<- ifelse(test, "webRootUrl", "rtoolsPath")
# cat("Test:",length(commandArgs()))

source(paste(fpath, "R/HTMLStream.R", sep = ""))
source(paste(fpath, "R/epitools_functions.r", sep = ""))

# extract command arguments 1 = se, 2 = sp, 3 = population size, 4 = number of diseased elements,
# 5 = sample size, 6 = number positive,
# 7 = method, 8 = type1 error, 9 = type2 error, 10  = max sample size, 11 = infinite population threshold
# method 1 = modified hypergeomertric, 2 = modified binomial, 3 = simple binomial
# cat("", a0[20:22])
a1<- type.convert(a0[8:17])
#  cat("", a1)

N<- a1          # population size
se<- a1           # test sensitivity
sp<- a1           # test specificity
dis<- a1          # number/prevalence of diseased elemnets
prev.type<- ifelse(dis < 1, 1, 0)      # 0 = number of diseased elements, 1 = prevalence
# n<- a1           # sample size
# n.pos<- a1        # observed number positive
type1<- a1        # type I error
type2<- a1        # type II error
method<- a1       # calculation method  0 = hypergeo, 1 = binom approx, 2 = simple binom
pop.threshold<- a1   # Infinite population threshold
max.ss<- a1       # maximum sample size
option<- 0       # calculation option - 0 = sample size, 1 = analyse data
digits<- a1         # number of digits in results
prec<- 10^-digits
prev<- ifelse(prev.type, dis, dis/N)
dis<- ifelse(prev.type, max(1, round(dis*N, 0)), dis)
method<- ifelse(N > pop.threshold, 2, method)

method.lst<- c("Modified hypergeometric exact", "Modified binomial approximation", "Simple binomial (large population)")
heading<- c("FreeCalc sample size estimation", "FreeCalc data analysis")
filename<- digest(Sys.time)
tmp.path<- paste(fpath, "tmp/", sep = "")
tmp.file<- paste(fpath, "tmp/", filename, sep = "")
sinkfile<- paste(fpath, "tmp/", filename, ".txt", sep="")   # fpath,
# cat(46)

inputs<- array("", dim = c(11, 1))
inputs[1:3,1]<- a1[1:3]
inputs[4,1]<- prev
inputs[5,1]<- dis
inputs[6:7,1]<- a1[5:6]
inputs[8,1]<- method.lst[method+1]
inputs[9:11,1]<- a1[8:10]
rownames(inputs)<- c("Population size", "Test sensitivity", "Test specificity", "Design prevalence",
"Diseased units", "Target Type I error", "Target Type II error", "Analysis method",
"Population threshold for binomial default", "Maximum sample size", "Digits")

# cat("method:", method)

# function to get cut-point for given sample size
get.cp<- function(n.cp, se, sp, type2) {
cp<- 0
SpH<- 0
while (SpH < 1-type2) {
cp<- cp+1                     # probability of observed result from diseas-free popn
SpH<- sph.binom(n.cp, cp, sp)
}
return (list("cp" = cp, "SpH" = SpH))
} # end of get.cp

# function to do sample size calcuations
get.ss<- function(N, se, sp, prev, type1, type2, dis, method, method.lst, maxSS) {
N1<- min(N, maxSS)
brks<- c(50, 100, 1000, 5000, 10000, Inf)
steps<- c(5, 10, 50, 100, 200)
step<- steps[which(N1 < brks)]
ss<- seq(0, N1, by = step)
ss<- 1
if (length(ss) == 1) ss<- N1
cp<- 0
SpH<- 0
SeH<- 0
P1<- 0
success<- F
for (s in 1:length(ss)) {
tmp<- get.cp(ss[s], se, sp, type2)
cp[s]<- tmp[]
SpH[s]<- tmp[]
if (identical(method, 2) || N > pop.threshold) {         # simple binomial
P1[s]<- 1-sep.binom.imperfect(ss[s], cp[s], se, sp, prev)
} else {                                               # modified hypergeometric exact
P1[s]<- 1-sep.freecalc(N,ss[s], cp[s],se,sp,prev)
}
SeH[s]<- 1-P1[s]
cp[s]<- cp[s]-1
if (P1[s] <= type1) {
success<- T
n1<- ss[s]
break
}
}  # end of s loop
if (success) {
ss[(s+1):(s+step)]<- (ss[s-1]+1):(ss[s-1]+step)
for (x in 1:step) {
tmp<- get.cp(ss[s+x], se, sp, type2)
cp[s+x]<- tmp[]
SpH[s+x]<- tmp[]
if (identical(method, 2) || N > pop.threshold) {         # simple binomial
P1[s+x]<- 1-sep.binom.imperfect(ss[s+x], cp[s+x], se, sp, prev)
} else {                                               # modified hypergeometric exact
P1[s+x]<- 1-sep.freecalc(N,ss[s+x], cp[s+x],se,sp,prev)
}
SeH[s+x]<- 1-P1[s+x]
cp[s+x]<- cp[s+x]-1
if (P1[s+x] <= type1) {
success<- T
n1<- ss[s+x]
break
}
} # end of x loop
result<- array("", dim = c(8, 1))
rownames(result)<- c("Required sample size:", "Cut-point number of positives:",
"Type I error:", "Type II error:", "Population-level sensitivity:",
"Population-level specificity:", "Interpretation:", "Method:")
result[1,1]<- n1
result[2,1]<- cp[s+x]
result[3,1]<- round(1-SeH[s+x], digits)
result[4,1]<- round(1-SpH[s+x], digits)
result[5,1]<- round(SeH[s+x], digits)
result[6,1]<- round(SpH[s+x], digits)
result[7,1]<- paste("If a random sample of ", n1, " units is taken from a population of ",
N, " and ", cp[s+x], " or fewer reactors are found, the probability that the population is diseased at a prevalence of ",
prev, " is ", round(1-SeH[s+x], digits), ".", sep = "")
result[8,1]<- method.lst[method+1]
return(list(success, "result" = result, "n" = ss[1:(s+x)], "seh" = SeH[1:(s+x)], "sph" = SpH[1:(s+x)], "cp" = cp[1:(s+x)], P1[1:(s+x)], "sam.size" = (s+x)))
} else {
result<- array("", dim = c(1, 1))
result[1,1]<- ifelse(identical(N1, N), "Unable to achieve required accuracy by sampling every unit",
paste("Unable to achieve required accuracy by sampling every unit up to the maximum sample size of ", maxSS, ".", sep = ""))
return(list(success, "result" = result))
} # end of if/else
#    return(list("seh"=SeH, "sph"=SpH, "cp"=cp, "sam.size"=n1, "success"=success))
} # end of get.ss function
# cat("", N)

tmp<- get.ss(N, se, sp, prev, type1, type2, dis, method, method.lst, max.ss)
# cat("", test)

success<- tmp[]
result<- tmp[]
if (success) {
ss<- tmp[]
SeH<- round(tmp[], digits)
SpH<- round(tmp[], digits)
cp.list<- tmp[]
P1<- round(tmp[], digits)
n<- tmp[]
cp<- cp.list[n]
result1<- cbind("n" = ss, SeH, SpH, "Cut-point" = cp.list, "Type 1 error" = P1, "Type 2 error" = 1-SpH)
}
tmp<- gsub("", "", result)
result.txt<- gsub("", "", tmp)
# cat("Test:", method)
file.name<- file(paste(tmp.file, "_result.xls", sep = ""), open = "wt")
writeLines(c(heading[option+1], date(), ""), con = file.name)
writeLines("Inputs", con = file.name)
write.table(inputs, file = file.name, sep = "\t", append = T, col.names = F)
writeLines(c("", "Results"), con = file.name)
write.table(result.txt, file = file.name, sep = "\t", append = T, col.names = F, row.names = T)
if (success) {
writeLines(c("", "Detailed Results"), con = file.name)
write.table(result1, file = file.name, sep = "\t", append = T, col.names = F, row.names = T)
}
close(file.name)

# output results
d1<- paste(substr(date(), 1, 10), substr(date(), 20,24), " @", substr(date(), 11, 16))