convest <- function(p,niter=100,plot=FALSE,report=FALSE,file="",tol=1e-06)
# Estimates pi0 using a convex decreasing density estimate
# Input: p=observed p-values,k=number of iterations,
# plot=TRUE plots and report=TRUE writes results of each iteration.
# Returns: An estimate of pi0
# The methology underlying the function can be found in the
# preprint: "Estimating the proportion of true null hypotheses,
# with application to DNA microarray data." that can be downloaded
# from http://www.math.ntnu.no/~mettela/
# Written by Egil Ferkingstad.
# Received from Mette Langaas 26 Jun 2004.
# Modified for limma by Gordon Smyth, 29 Oct 2004, 28 May 2005.
# Report modified by Marcus Davy, 24 June 2007. Implemented and edited by Gordon Smyth, 9 Sep 2012, 12 Apr 2020.
{
if(!length(p)) return(NA)
if(anyNA(p)) stop("Missing values in p not allowed")
if(any(p<0 | p>1)) stop("All p-values must be between 0 and 1")
k <- niter
# accuracy of the bisectional search for finding a new
# convex combination of the current iterate and the mixing density
ny <- tol
p <- sort(p)
m <- length(p)
p.c <- ceiling(100*p)/100
p.f <- floor(100*p)/100
t.grid <- (1:100)/100
x.grid <- (0:100)/100
t.grid.mat <- matrix(t.grid,ncol=1)
f.hat <- rep(1,101) #f.hat at the x-grid
f.hat.p <- rep(1,m) #f.hat at the p-values
theta.hat <- 0.01*which.max(apply(t.grid.mat,1,function(theta) sum((2*(theta-p)*(p<theta)/theta^2))))
f.theta.hat <- 2*(theta.hat-x.grid)*(x.grid<theta.hat)/theta.hat^2 # f.theta.hat at the x-grid
f.theta.hat.p <- 2*(theta.hat-p)*(p<theta.hat)/theta.hat^2 # f.theta.hat at the p-values
i<-1
j<-0
thetas <- numeric()
if(report) cat("j\tpi0\ttheta.hat\t\tepsilon\tD\n", file=file, append=FALSE)
for (j in 1:k) {
f.hat.diff <- (f.hat.p - f.theta.hat.p)
if (sum(f.hat.diff/f.hat.p) > 0)
eps <- 0
else {
l <- 0
u <- 1
while (abs(u-l)>ny) {
eps <- (l+u)/2
if(sum((f.hat.diff/((1-eps)*f.hat.p+eps*f.theta.hat.p))[f.hat.p>0])<0)
l <- eps
else
u <- eps
}
}
f.hat <- (1-eps)*f.hat + eps*f.theta.hat
pi.0.hat <- f.hat[101]
d <- sum(f.hat.diff/f.hat.p)
if(report) cat(j, "\t",pi.0.hat, "\t",theta.hat,"\t",eps, "\t",d, "\n", file=file, append=TRUE)
f.hat.p <- 100*(f.hat[100*p.f+1]-f.hat[100*p.c+1])*(p.c-p)+f.hat[100*p.c+1]
theta.hat <- 0.01*which.max(apply(t.grid.mat,1,function(theta) sum((2*(theta-p)*(p<theta)/theta^2)/f.hat.p)))
f.theta.hat <- 2*(theta.hat-x.grid)*(x.grid<theta.hat)/theta.hat^2
f.theta.hat.p <- 2*(theta.hat-p)*(p<theta.hat)/theta.hat^2
if (sum(f.theta.hat.p/f.hat.p)<sum(1/f.hat.p)) { # check if the Unif[0,1]-density is the new "f.theta.hat"
theta.hat <- 0
f.theta.hat <- rep(1,101)
f.theta.hat.p <- rep(1,m)
}
if (sum(thetas==theta.hat)==0) {
thetas[i] <- theta.hat
thetas <- sort(thetas)
i <- i + 1
}
# pi.0.hat <- f.hat[101]
if (plot) {
plot(x.grid,f.hat,type="l",main=paste(format(round(pi.0.hat,5),digits=5)),ylim=c(0,1.2))
points(thetas,f.hat[100*thetas+1],pch=20,col = "blue")
}
}
pi.0.hat
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.