####################
# Functions
####################
trigger.build <- function(exp = exp, exp.pos = exp.pos, marker = marker, marker.pos = marker.pos){
if(nrow(exp)!=nrow(exp.pos)||nrow(marker)!=nrow(marker.pos)||ncol(exp)!=ncol(marker)){
stop("Check matrix dimensions")
}
triggerobj <- new("trigger", exp = exp, exp.pos = exp.pos, marker = marker, marker.pos = marker.pos)
}
solvemat<-function(Y,x){
coef = solve.qr(qr(x), t(Y))
Yhat = crossprod(coef, t(x))
}
## compute likage for one expression trait with one locus (could be a sex chromosome locus)
link.stat.c <- function(exp, genotype, gender=NULL) {
n <- as.integer(length(exp))
if(is.null(gender)){ gender <- rep(1, n) }
oo <- NULL
for (g in unique(gender)){
idx <- which(gender==g)
geno <- genotype[idx]
trait <- exp[idx]
ni <- as.integer(length(trait))
ng <- as.integer(length(table(geno)))
geno2 <- rep(0, length(geno))
for (i in 1:ng){
geno2[geno==unique(as.vector(geno))[i]] <- i
}
# depend on the proper type coming in!
storage.mode(trait) <- "double"
storage.mode(geno2) <- "integer"
lik0 <- double(1)
lik1 <- double(1)
#.C("link_stat", ni, trait, geno2, ng, lik0, lik1, DUP=FALSE, PACKAGE="trigger")
out <- .C("link_stat", ni, trait, geno2, ng, lik0, lik1, DUP=TRUE)
lik0 <- out[[5]]
lik1 <- out[[6]]
oo <- cbind(oo, c(lik0, lik1))
}
foo <- n*log(rowSums(oo))
return(foo[1]-foo[2])
}
# As link.stat.c, but with matrix arguments. Much faster than apply()
link.stat.xx.c <- function(exp, genotype, gender=NULL) {
n <- as.integer(ncol(exp))
if(is.null(gender)){ gender <- rep(1, n) }
nexp <- as.integer(nrow(exp))
ngeno <- as.integer(nrow(genotype))
oo <- NULL
for (g in unique(gender)){
idx <- which(gender==g)
geno <- genotype[, idx]
trait <- exp[, idx]
ni <- as.integer(length(idx))
ng <- as.integer(length(table(geno)))
geno2 <- rep(0, nrow(geno)*ncol(geno))
for (i in 1:ng){
geno2[geno==unique(as.vector(geno))[i]] <- i
}
dim(geno2) <- c(nrow(geno), ncol(geno))
storage.mode(trait) <- "double"
storage.mode(geno2) <- "integer"
lik0 <- double(nexp*ngeno)
lik1 <- double(nexp*ngeno)
#.C("link_stat_xx", ni , nexp, trait, ngeno,geno2, ng, lik0, lik1, DUP=FALSE, PACKAGE="trigger")
out <- .C("link_stat_xx", ni , nexp, trait, ngeno,
geno2, ng, lik0, lik1, DUP=TRUE)
lik0 <- out[[7]]
lik1 <- out[[8]]
oo <- cbind(oo, c(lik0, lik1))
}
foo <- n*log(rowSums(oo))
foo <- matrix(foo,nrow=nexp*ngeno)
stat <- foo[,1]-foo[,2]
dim(stat)<-c(nexp, ngeno)
return(stat)
}
sec.link.stat.c <- function(exp, cisexp, genotype, gender=NULL) {
n <- as.integer(length(exp))
if(is.null(gender)){ gender <- rep(1, n) }
oo <- NULL
for (g in unique(gender)){
idx <- which(gender==g)
geno <- genotype[idx]
trait <- exp[idx]
cistrait <- cisexp[idx]
ni <- as.integer(length(trait))
ng <- as.integer(length(table(geno)))
geno2 <- rep(0, length(geno))
for (i in 1:ng){
geno2[geno==unique(as.vector(geno))[i]] <- i
}
lik0 <- double(1)
lik1 <- double(1)
storage.mode(trait) <- storage.mode(cistrait) <- "double"
storage.mode(geno2) <- "integer"
#.C("sec_link_stat", ni, trait, cistrait,geno2, ng, lik0, lik1, DUP=FALSE, PACKAGE="trigger")
out <- .C("sec_link_stat", ni, trait, cistrait,
geno2, ng, lik0, lik1, DUP=TRUE)
lik0 <- out[[6]]
lik1 <- out[[7]]
oo <- cbind(oo, c(lik0, lik1))
}
foo <- n*log(rowSums(oo))
return(foo[1]-foo[2])
}
# As sec.link.stat but with matrix for exp
sec.link.stat.x.c <- function(exp, cisexp, genotype, gender=NULL) {
n <- as.integer(ncol(exp))
if(is.null(gender)){ gender <- rep(1, n) }
nexp <- as.integer(nrow(exp))
oo <- NULL
for (g in unique(gender)){
idx <- which(gender==g)
geno <- genotype[idx]
trait <- exp[, idx]
cistrait <- cisexp[idx]
ni <- as.integer(length(idx))
ng <- as.integer(length(table(geno)))
geno2 <- rep(0, length(geno))
for (i in 1:ng){
geno2[geno==unique(as.vector(geno))[i]] <- i
}
storage.mode(trait) <- storage.mode(cistrait) <- "double"
storage.mode(geno2) <- "integer"
lik0 <- double(nexp)
lik1 <- double(nexp)
#.C("sec_link_stat_x", ni, nexp,trait, cistrait, geno2, ng, lik0, lik1, DUP=FALSE, PACKAGE="trigger")
out <- .C("sec_link_stat_x", ni, nexp, trait, cistrait, geno2, ng, lik0, lik1, DUP=TRUE)
lik0 <- out[[7]]
lik1 <- out[[8]]
oo <- cbind(oo, c(lik0, lik1))
}
foo <- n*log(rowSums(oo))
foo <- matrix(foo,nrow=nexp)
stat <- foo[,1]-foo[,2]
return(stat)
}
condi.indep.stat.c <- function(exp, cisexp, genotype, gender=NULL) {
n <- as.integer(length(exp))
if(is.null(gender)){ gender <- rep(1, n) }
oo <- 0
for (g in unique(gender)){
idx <- which(gender==g)
geno <- genotype[idx]
trait <- exp[idx]
cistrait <- cisexp[idx]
ni <- as.integer(length(trait))
ng <- as.integer(length(table(geno)))
geno2 <- rep(0, length(geno))
for (i in 1:ng){
geno2[geno==unique(as.vector(geno))[i]] <- i
}
r <- double(1)
storage.mode(trait) <- storage.mode(cistrait) <- "double"
storage.mode(geno2) <- "integer"
#.C("condi_indep_stat", ni, trait, cistrait,geno2, ng, r, DUP=FALSE, PACKAGE="trigger")
out <- .C("condi_indep_stat", ni, trait, cistrait,
geno2, ng, r, DUP=TRUE)
r <- out[[6]]
oo <- oo + r
}
return(oo)
}
condi.indep.stat.x.c <- function(exp, cisexp, genotype, gender=NULL) {
n <- as.integer(ncol(exp))
if(is.null(gender)){ gender <- rep(1, n) }
nexp <- as.integer(nrow(exp))
oo <- rep(0, nexp)
for (g in unique(gender)){
idx <- which(gender==g)
geno <- genotype[idx]
trait <- exp[, idx]
cistrait <- cisexp[idx]
ni <- as.integer(length(idx))
ng <- as.integer(length(table(geno)))
geno2 <- rep(0, length(geno))
for (i in 1:ng){
geno2[geno==unique(as.vector(geno))[i]] <- i
}
storage.mode(trait) <- storage.mode(cistrait) <- "double"
storage.mode(geno2) <- "integer"
r <- double(nexp)
#.C("condi_indep_stat_x", ni, nexp,trait, cistrait, geno2, ng, r, DUP=FALSE, PACKAGE="trigger")
out <- .C("condi_indep_stat_x", ni, nexp,
trait, cistrait, geno2, ng, r, DUP=TRUE)
r <- out[[7]]
oo <- oo+ r
}
return(oo)
}
condi.indep.stat.rx.c <- function(exp, cisexp, genotype, gender=NULL) {
n <- as.integer(ncol(cisexp))
if(is.null(gender)){ gender <- rep(1, n) }
nexp <- as.integer(nrow(cisexp))
oo <- rep(0, nexp)
for (g in unique(gender)){
idx <- which(gender==g)
geno <- genotype[idx]
trait <- exp[idx]
cistrait <- cisexp[, idx]
ni <- as.integer(length(idx))
ng <- as.integer(length(table(geno)))
geno2 <- rep(0, length(geno))
for (i in 1:ng){
geno2[geno==unique(as.vector(geno))[i]] <- i
}
storage.mode(trait) <- storage.mode(cistrait) <- "double"
storage.mode(geno2) <- "integer"
r <- double(nexp)
out <- .C("condi_indep_stat_rx", ni, nexp,
trait, cistrait, geno2, ng, r, DUP=TRUE, PACKAGE = "trigger")
r <- out[[7]]
oo <- oo+ r
}
return(oo)
}
### MULTI-LOCUS LINKAGE FUNCTIONS
filt <- function(marker, w=NULL) {
m <- nrow(marker)
k <- ncol(marker)/2
u <- rep(TRUE,m)
u[w] <- FALSE
ww <- w-1
while((ww > 0) && (sum(marker[w,] != marker[ww,]) < k)) {
u[ww] <- FALSE
ww <- ww-1
}
ww <- w+1
while((ww <= m) && (sum(marker[w,] != marker[ww,]) < k)) {
u[ww] <- FALSE
ww <- ww+1
}
return(u)
}
########## Identify the eQTLs (linkage hotspots).
### This function returns an eigen-R2 measure for each locus in the genome. The eigen-R2 measure of a locus quantifies the proportion
### of genome-wide expression variation that can be explained by that locus.
get.v <- function(x, eigenG, SST, df0, weights, adjust,N) {
model <- model.matrix(~1+x)
df <- ncol(model)
H <- model %*% solve(t(model) %*% model) %*% t(model)
res <- eigenG - t(H %*% t(eigenG))
SSR <- apply(res, 1, function(x) {sum((x-mean(x))^2)})
R2s <- 1- SSR/SST
v <- sum(R2s*weights)
if (adjust == TRUE) {
v <- 1-(1-v)*(N-df0)/(N-df)
}
return(v)
}
#### Plots
eqtlPlot <- function(object, ylim=NULL){
marker.pos <- object@marker.pos
exp.pos <- object@exp.pos
marker <- object@marker
eqtl.R2 <- object@eqtl.R2
if(length(eqtl.R2)==0){
stop("Run eqtl() function before plotting")
}
uchr.name <- unique(as.vector(marker.pos[, 1]))
nchr <- length(uchr.name)
idx <- which(uchr.name=="X")
if (length(idx)>0) {
chr.name <- c(sort(as.integer(uchr.name[-idx])), uchr.name[idx])
} else {
chr.name <- sort(as.integer(uchr.name))
}
markerp <- rep(0, nrow(marker.pos))
ranget <- 0
for (i in 1:nchr){
idxm <- which(marker.pos[,1]==chr.name[i])
ss <- min(marker.pos[idxm,2])
ee <- max(marker.pos[idxm,2])
markerp[idxm] <- ranget[i] + marker.pos[idxm,2]-ss
ranget <- c(ranget, ranget[i] + (ee-ss))
}
totl <- max(ranget)
if (is.null(ylim)) ylim <- c(0, max(eqtl.R2)*1.1)
plot(markerp, eqtl.R2, xlim=c(1, totl), ylim=ylim, xlab="marker position", ylab="eqtl-R2 value",xaxt="n", "n", pch=16, cex=.5, main = "Eigen-R2")
lines(markerp, eqtl.R2)
#abline(h=1/(ncol(marker)-1))
axis(1,at= ranget, labels=F)
axis(1,at= c(ranget[-1] + ranget[-(1+nchr)])/2, tick=F, labels = chr.name, cex.axis=.7)
}
linkPlot<-function(x, cutoff = 0){
marker.pos <- x@marker.pos
exp.pos <- x@exp.pos
if(length(x@pvalue)==0){
stop("Run link() function before plotting")
}
p <- x@pvalue
pt <- which(p<=cutoff)
if (length(pt)<10) stop("Please choose a more liberal cutoff.")
pt.y <- as.integer(pt/nrow(p))+1
pt.x <- pt-(pt.y-1)*nrow(p)
pt.y[pt.x==0] <- pt.y[pt.x==0] -1
pt.x[pt.x==0] <- nrow(p)
gene.mid <- (exp.pos[,2]+exp.pos[,3])/2
uchr.m <- unique(as.vector(marker.pos[, 1]))
nchr.m <- length(uchr.m)
idx <- which(uchr.m=="X")
if (length(idx)>0) {
chr.m <- c(sort(as.integer(uchr.m[-idx])), uchr.m[idx])
} else {
chr.m <- sort(as.integer(uchr.m))
}
uchr.e <- unique(as.vector(exp.pos[, 1]))
nchr.e <- length(uchr.e)
idx <- which(uchr.e=="X")
if (length(idx)>0) {
chr.e <- c(sort(as.integer(uchr.e[-idx])), uchr.e[idx])
} else {
chr.e <- sort(as.integer(uchr.e))
}
markerp <- rep(0, nrow(marker.pos))
genep <- rep(0, nrow(exp.pos))
rangem <- rangee <- 0
for (i in 1:nchr.m){
idxm <- which(marker.pos[,1]==chr.m[i])
ss <- min(marker.pos[idxm,2])
ee <- max(marker.pos[idxm,2])
markerp[idxm] <- rangem[i] + marker.pos[idxm,2]-ss+1
rangem <- c(rangem, rangem[i] + (ee-ss)+1)
}
for (i in 1:nchr.e){
idxe <- which(exp.pos[,1]==chr.e[i])
ss <- min(exp.pos[idxe,2])
ee <- max(exp.pos[idxe,3])
genep[idxe] <- rangee[i] + gene.mid[idxe]-ss+1
rangee <- c(rangee, rangee[i] + (ee-ss)+1)
}
totm <- max(rangem)
tote <- max(rangee)
plot(markerp[pt.y], genep[pt.x], xlim=c(1, totm), ylim=c(1, tote), xlab="marker position",
ylab="expression-trait position",xaxt="n",yaxt="n",pch=16, cex=.5,
main = paste("Cutoff =", cutoff, sep = ""))
axis(2,at= rangee, labels=F)
axis(2,at= c(rangee[-1] + rangee[-(1+nchr.e)])/2, tick=F, labels = chr.e, cex.axis=.7)
axis(1,at= rangem, labels=F)
axis(1,at= c(rangem[-1] + rangem[-(1+nchr.m)])/2, tick=F, labels = chr.m, cex.axis=.7)
}
mlinkPlot <- function(object, qcut = qcut, bin.size=NULL) {
marker.pos <- object@marker.pos
exp.pos <- object@exp.pos
mlink.obj <-object@mlink
idx <- which(mlink.obj$qvalue <= qcut)
if (length(idx)<10) stop("Please choose a more liberal q-value cutoff.")
qtl <- (mlink.obj$qtl)[idx,]
qtl <- t(apply(qtl, 1, sort, decreasing=T))
uchr.m <- unique(as.vector(marker.pos[, 1]))
nchr.m <- length(uchr.m)
idx <- which(uchr.m=="X")
if (length(idx)>0) {
chr.m <- c(sort(as.integer(uchr.m[-idx])), uchr.m[idx])
} else {
chr.m <- sort(as.integer(uchr.m))
}
markerp <- rep(0, nrow(marker.pos))
if (is.null(bin.size)) bin.size <-1
binpos <- as.integer(marker.pos[,2]/bin.size)+1
rangem <- 0
for (i in 1:nchr.m){
idxm <- which(marker.pos[,1]==chr.m[i])
ss <- min(binpos[idxm])
ee <- max(binpos[idxm])
markerp[idxm] <- rangem[i] + binpos[idxm]-ss+1
rangem <- c(rangem, rangem[i] + (ee-ss)+1)
}
totm <- max(rangem)
plot(markerp[qtl[,1]], markerp[qtl[,2]], xlim=c(1, totm), ylim=c(1, totm), xlab="marker position", ylab="marker position",xaxt="n",yaxt="n","n", cex=.5)
oov <- apply(cbind(markerp[qtl[,1]], markerp[qtl[,2]]), 1, paste, collapse=",")
oon <- table(oov)
noon <- names(oon)
for (i in 1:length(names(oon))) {
pos <- as.integer(strsplit(noon[i],",")[[1]])
cnt <- as.character(oon[i])
text(pos[1]-0.5, pos[2]-0.5, cnt, cex=0.5)
}
abline(0, 1, lty=2)
axis(2,at= rangem, labels=F)
axis(2,at= c(rangem[-1] + rangem[-(1+nchr.m)])/2, tick=F, labels = chr.m, cex.axis=.7)
axis(1,at= rangem, labels=F)
axis(1,at= c(rangem[-1] + rangem[-(1+nchr.m)])/2, tick=F, labels = chr.m, cex.axis=.7)
}
### GET PERMUTATION indEX FUNCTION ###
get.loc.markers <- function(exp.index, exp.pos, marker, marker.pos, window.size = NULL) {
marker.pos <- as.matrix(marker.pos)
exp.pos <- as.matrix(exp.pos)
exp.chr <- exp.pos[exp.index, 1]
if (is.null(window.size)) {
midx <- which(marker.pos[, 1] == exp.chr)
return(midx)
} else{
exp.coord <- range(as.numeric(exp.pos[exp.index, 2:3]))
exp.length <- exp.coord[2] - exp.coord[1]
exp.range <- exp.coord + c(-1, 1) * (window.size - exp.length)/2
midx <- which((marker.pos[, 1] == exp.chr) & (as.numeric(marker.pos[, 2]) >= exp.range[1]) & (as.numeric(marker.pos[, 2]) <= exp.range[2]))
if (length(midx) > 1) {
return(midx)
} else {
tidxs <- which(as.vector(marker.pos[, 1]) == exp.chr)
mleft <- as.numeric(marker.pos[tidxs, 2]) - exp.range[1]
mleft[mleft>0] <- min(mleft)
mright <- as.numeric(marker.pos[tidxs, 2])- exp.range[2]
mright[mright<0] <- max(mright)
mm1 <- tidxs[order(mleft, decreasing=T)[1:2]]
mm2 <- tidxs[order(mright, decreasing=F)[1:2]]
mm <- unique(c(mm1, mm2))
if (length(mm)>1) {
return(mm)
}else{
stop("Please select a larger window.size.")
}
} }
}
perm.idx.fun <- function(n, B) {
Idx.matrix <- matrix(rep(1:n, B), byrow = T, nrow = B)
Idx.matrix <- apply(Idx.matrix, 1, sample)
return(Idx.matrix)
}
order.c <- function(x) {
out <- integer(length(x))
storage.mode(x) <- "double"
#.C("order_c",x,as.integer(length(x)),out,DUP=FALSE, PACKAGE="trigger")
hold <- .C("order_c",x,as.integer(length(x)),out,DUP=TRUE)
out <- hold[[3]]
return(out)
}
mergeorder.c <- function(x1, x2) {
storage.mode(x1) <- "double";
storage.mode(x2) <- "double";
n1<-as.integer(length(x1))
n2<-as.integer(length(x2))
out<-integer(n1+n2)
#.C("mergeorder",n1,x1,n2,x2,out,DUP=FALSE, PACKAGE="trigger")
hold <- .C("mergeorder",n1,x1,n2,x2,out,DUP=TRUE)
out <- hold[[5]]
return(out)
}
get.pi0 <- function (p = NULL, lambda = seq(0, 0.9, 0.05),
pi0.method = "smoother", fdr.level = NULL, robust = FALSE,
gui = FALSE, smooth.df = 3, smooth.log.pi0 = FALSE)
{
if (min(p) < 0 || max(p) > 1) {
print("ERROR: p-values not in valid range.", quote=FALSE)
return(0)
}
if (length(lambda) > 1 && length(lambda) < 4) {
print(paste("ERROR: If length of lambda greater than 1, ",
"you need at least 4 values."), quote=FALSE)
return(0)
}
if (length(lambda) > 1 && (min(lambda) < 0 || max(lambda) >= 1)) {
print("ERROR: Lambda must be within [0, 1).", quote=FALSE)
return(0)
}
m <- length(p)
if (length(lambda) == 1) {
if (lambda < 0 || lambda >= 1) {
print("ERROR: Lambda must be within [0, 1).", quote=FALSE)
return(0)
}
pi0 <- mean(p >= lambda)/(1 - lambda)
pi0 <- min(pi0, 1)
pi0 <- max(pi0, 0)
} else {
pi0 <- rep(0, length(lambda))
for (i in 1:length(lambda)) {
pi0[i] <- mean(p >= lambda[i])/(1 - lambda[i])
}
if (pi0.method == "smoother") {
if (smooth.log.pi0) pi0 <- log(pi0)
spi0 <- smooth.spline(lambda, pi0, df = smooth.df)
pi0 <- predict(spi0, x = max(lambda))$y
if (smooth.log.pi0) pi0 <- exp(pi0)
pi0 <- min(pi0, 1)
pi0 <- max(pi0, 0)
} else if (pi0.method == "bootstrap") {
minpi0 <- min(pi0)
mse <- rep(0, length(lambda))
pi0.boot <- rep(0, length(lambda))
for (i in 1:100) {
p.boot <- sample(p, size = m, replace = TRUE)
for (i in 1:length(lambda)) {
pi0.boot[i] <- mean(p.boot > lambda[i])/(1 - lambda[i])
}
mse <- mse + (pi0.boot - minpi0)^2
}
pi0 <- min(pi0[mse == min(mse)])
pi0 <- min(pi0, 1)
pi0 <- max(pi0, 0)
} else {
print("ERROR: 'pi0.method' must be one of 'smoother' or 'bootstrap'.", quote=FALSE)
return(0)
}
}
return(pi0)
}
find.cis.genes<-function(out.em, cross, chr.s, marker, marker.pos, exp, exp.pos, thr = thr){
out.em.s = summary(out.em)
n.sig = length(unique(out.em.s$chr))
pos.s = as.numeric(max(out.em, chr = chr.s)$pos)
int.bayes = bayesint(out.em, chr.s, 0.95)
int.lod = lodint(out.em, chr.s, 1.5)
int.comb = rbind(int.bayes, int.lod)
pos.left = min(int.comb$pos); pos.right = max(int.comb$pos)
qtl.left = find.marker(cross, chr.s, pos.left)
qtl.right = find.marker(cross, chr.s, pos.right)
qtl.max = find.marker(cross, chr.s, pos.s)
markernames = rownames(marker)
pos.left = marker.pos[which(markernames == qtl.left), 2]
pos.right = marker.pos[which(markernames == qtl.right), 2]
marker.max = which(markernames == qtl.max)
prox.genes = which(exp.pos[,1]==chr.s&exp.pos[,2]>=pos.left&exp.pos[,3]<=pos.right)
result = list(marker.max = marker.max, prox.genes = prox.genes)
}
sva.fit<-function(exp, qtl, traitid = NULL, nsv = 0){
m = nrow(exp)
n = ncol(exp)
exp.comb = exp
mod = model.matrix(~1+as.factor(qtl))
if(nsv == 0){
H = sva(exp.comb, mod)
}
if(nsv != 0){
H = twostepsva.build(exp.comb, mod, n.sv = nsv)
}
n.sv <- H$n.sv
resids <- exp.comb
if (n.sv>0){
use.var <- matrix(rep(FALSE, n.sv*m), ncol = n.sv)
pp <- matrix(rep(FALSE, n.sv*m), ncol = n.sv)
for(i in 1:n.sv) {
pp[,i] <- sv.support(exp,H$sv[,i])
use.var[,i] <- rank(pp[,i]) <= (m-m*get.pi0(pp[,i]))
}
for (i in 1:nrow(exp.comb)){
if (sum(use.var[i,])>0) {
resids[i, ] <- lsfit(H$sv[, use.var[i,]], exp.comb[i,])$residuals
}
}
resids <- t(apply(resids, 1, function(x) qnorm(rank(x)/(n+1))))
} else {
resids <- t(apply(exp, 1, function(x) qnorm(rank(x)/(n+1))))
}
result = list(t1.fit = resids[1:m,], t2.fit = resids[traitid,], n.sv = n.sv)
return(result)
}
traitmap.fun <- function(exp, trait, cis.list, markermorph, B= 5, norm=TRUE, df0){
m.id = as.numeric(unique(cis.list[,1]))
n = ncol(exp)
if (norm) exp <- t(apply(exp, 1, function(x) qnorm(rank(x)/(n+1))))
if (norm) trait <- qnorm(rank(trait)/(n+1))
qtl = markermorph[m.id, ]
qtl.mod = model.matrix(~1 + qtl)
ps.list <- list()
#for(i in 1:nrow(cis.list)){
# g.id = as.numeric(cis.list[i,2])
condi <- condi.indep.stat.rx.c(exp = trait, cisexp = exp, genotype = qtl)
condi <- condi[!is.na(condi)]
stat0 <- NULL
for (k in 1:B){
trait.null = c()
for (l in unique(qtl)){ trait.null[qtl==l] <- sample(trait[qtl==l])}
resids0 <- qnorm(rank(trait.null)/(n+1))
oo <- condi.indep.stat.rx.c(exp = trait.null, cisexp = exp, genotype = qtl)
stat0 = c(stat0, oo)
}
ps <- unlist(lapply(condi, function(x,stat0){ mean(stat0<=x)} , stat0=stat0),use.names=FALSE)[as.numeric(cis.list[,2])]
names(ps) = cis.list[, 3]
#ps.list[[cis.list[i ,3]]] <- ps
return(ps)
}
########################################################################################
#Title: Extraction and Analysis of Differential Gene Expression
#Version: 2.0
#Author: John D. Storey <jstorey@princeton.edu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
########################################################################################
edge.lfdr <- function(p, trunc=TRUE, monotone=TRUE, transf=c("probit", "logit"), adj=1.5, eps=10^-8, pi0 = NULL, ...) {
if(is.null(pi0)) pi0 = edge.qvalue(p, ...)$pi0
n = length(p)
transf = match.arg(transf)
if(transf=="probit") {
p = pmax(p, eps)
p = pmin(p, 1-eps)
x = qnorm(p)
myd = density(x, adjust=adj)
mys = smooth.spline(x=myd$x, y=myd$y)
y = predict(mys, x)$y
lfdr = pi0*dnorm(x)/y
}
if(transf=="logit") {
x = log((p+eps)/(1-p+eps))
myd = density(x, adjust=adj)
mys = smooth.spline(x=myd$x, y=myd$y)
y = predict(mys, x)$y
dx = exp(x)/(1+exp(x))^2
lfdr = pi0*dx/y
}
if(trunc) {lfdr[lfdr > 1] = 1}
if(monotone) {
lfdr = lfdr[order(p)]
for(i in 2:n) {
if(lfdr[i] < lfdr[i-1]) {lfdr[i] = lfdr[i-1]}
}
lfdr = lfdr[rank(p)]
}
return(lfdr)
}
edge.qvalue <- function(p,lambda = seq(0, 0.9, 0.05), pi0.method = "smoother", fdr.level = NULL, robust = FALSE,smooth.df = 3, smooth.log.pi0 = FALSE, ...) {
err.func <- "edge.qvalue"
if (min(p) < 0 || max(p) > 1) {
err.msg(err.func,"P-values not in valid range.")
return(invisible(1))
}
if (length(lambda) > 1 && length(lambda) < 4) {
err.msg(err.func,"If length of lambda greater than 1, you need at least 4 values.")
return(invisible(1))
}
if (length(lambda) > 1 && (min(lambda) < 0 || max(lambda) >= 1)) {
err.msg(err.func,"Lambda must be in [0,1).")
return(invisible(1))
}
m <- length(p)
if (length(lambda) == 1) {
if (lambda < 0 || lambda >= 1) {
err.msg(err.func,"Lambda must be in [0,1).")
return(invisible(1))
}
pi0 <- mean(p >= lambda)/(1 - lambda)
pi0 <- min(pi0, 1)
} else {
pi0 <- rep(0, length(lambda))
for (i in 1:length(lambda)) {
pi0[i] <- mean(p >= lambda[i])/(1 - lambda[i])
}
if (pi0.method == "smoother") {
if (smooth.log.pi0){
pi0 <- log(pi0)
spi0 <- smooth.spline(lambda, pi0, df = smooth.df)
pi0 <- predict(spi0, x = max(lambda))$y
}
if (smooth.log.pi0) {
pi0 <- exp(pi0)
}
pi0 <- min(pi0, 1)
}
else if (pi0.method == "bootstrap") {
minpi0 <- min(pi0)
mse <- rep(0, length(lambda))
pi0.boot <- rep(0, length(lambda))
for (i in 1:100) {
p.boot <- sample(p, size = m, replace = TRUE)
for (i in 1:length(lambda)) {
pi0.boot[i] <- mean(p.boot > lambda[i])/(1 - lambda[i])
}
mse <- mse + (pi0.boot - minpi0)^2
}
pi0 <- min(pi0[mse == min(mse)])
pi0 <- min(pi0, 1)
}
else {
err.msg(err.func,"'pi0.method' must be one of 'smoother' or 'bootstrap'")
return(invisible(1))
}
}
if (pi0 <= 0) {
err.msg(err.func,"The estimated pi0 <= 0. Check that you have valid\np-values or use another lambda method.")
return(invisible(1))
}
if (!is.null(fdr.level) && (fdr.level <= 0 || fdr.level > 1)) {
err.msg(err.func,"'fdr.level' must be within (0,1].")
return(invisible(1))
}
u <- order(p)
qvalue.rank <- function(x) {
idx <- sort.list(x)
fc <- factor(x)
nl <- length(levels(fc))
bin <- as.integer(fc)
tbl <- tabulate(bin)
cs <- cumsum(tbl)
tbl <- rep(cs, tbl)
tbl[idx] <- tbl
return(tbl)
}
v <- qvalue.rank(p)
qvalue <- pi0 * m * p/v
if (robust) {
qvalue <- pi0 * m * p/(v * (1 - (1 - p)^m))
}
qvalue[u[m]] <- min(qvalue[u[m]], 1)
for (i in (m - 1):1) {
qvalue[u[i]] <- min(qvalue[u[i]], qvalue[u[i + 1]], 1)
}
if (!is.null(fdr.level)) {
retval <- list(call = match.call(), pi0 = pi0, qvalues = qvalue, pvalues = p, fdr.level = fdr.level, significant = (qvalue <= fdr.level), lambda = lambda)
}
else {
retval <- list(call = match.call(), pi0 = pi0, qvalues = qvalue, pvalues = p, lambda = lambda)
}
class(retval) <- "qvalue"
return(retval)
}
err.msg <- function(err.func = "edge",msg) {
cat('\n')
cat('\t')
cat('ERROR in the',err.func,'function: ','\n')
cat('\t',msg,'\n\n')
}
edge.pvalue <- function(stat, stat0, pool=TRUE) {
err.func <- "edge.pvalue"
m <- length(stat)
if(pool==TRUE) {
if(is.matrix(stat0)) {stat0 <- as.vector(stat0)}
m0 <- length(stat0)
v <- c(rep(T, m), rep(F, m0))
v <- v[order(c(stat,stat0), decreasing = TRUE)]
u <- 1:length(v)
w <- 1:m
p <- (u[v==TRUE]-w)/m0
p <- p[rank(-stat)]
p <- pmax(p,1/m0)
} else {
if(is.vector(stat0)) {
err.msg(err.func,"stat0 must be a matrix.")
return(invisible(1))
}
if(ncol(stat0)==m) {stat0 <- t(stat0)}
if(nrow(stat0)!=m){
err.msg(err.func,"Number of rows of stat0 must equal length of stat.")
return(invisible(1))
}
stat0 <- (stat0 - matrix(rep(stat,ncol(stat0)),byrow=FALSE,nrow=m)) >= 0
p <- apply(stat0,1,mean)
p <- pmax(p,1/ncol(stat0))
}
return(p)
}
sv.support <- function(dat,y){
### Function by Jeff Leek and John Storey
n <- dim(dat)[2]
m <- dim(dat)[1]
p <- rep(0,m)
one <- rep(1,n)
Id <- diag(one)
X <- cbind(one,y)
XXi <- solve(t(X)%*%X)
resid <- t((Id- X%*%XXi%*%t(X))%*%t(dat))
est <- (XXi%*%t(X)%*%t(dat))[2,]
se <- sqrt(XXi[2,2]*resid^2%*%rep(1,n)/(n-2))
p <- 2*(1-pt(abs(est/se),(n-2)))
return(p)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.