printtipWeights <- function(object, design = NULL, weights = NULL, method="genebygene", layout = object$printer, maxiter=50, tol = 1e-10, trace = FALSE)
# Compute print-tip quality weights
# Matt Ritchie
# 21 Sep 2006. Last revised 16 Jan 2008.
# Gordon Smyth simplified argument checking to use getEAWP, 9 Mar 2008.
{
# Check arguments
y <- getEAWP(object)
if(is.null(design))
design <- matrix(1,ncol(y$exprs),1)
else
design <- as.matrix(design)
if(mode(design) != "numeric") stop("design must be a numeric matrix")
ne <- nonEstimable(design)
if(!is.null(ne)) cat("Coefficients not estimable:",paste(ne,collapse=" "),"\n")
if(missing(weights) && !is.null(y$weights)) weights <- y$weights
method <- match.arg(method,c("genebygene","reml"))
M <- y$exprs
p <- ncol(design)
# cols <- seq(1:p)
QR <- qr(design)
nparams <- QR$rank # ncol(design)
nprobes <- nrow(M)
narrays <- ncol(M)
if(narrays < 3) stop("too few arrays")
if(nprobes < narrays) stop("too few probes")
if(is.null(layout)) stop("printer layout information must be specified")
ngr <- layout$ngrid.r
ngc <- layout$ngrid.c
nspots <- layout$nspot.r * layout$nspot.c
nprobes2 <- ngr*ngc*nspots
if(nprobes2 != nprobes) stop("printer layout information does not match M row dimension")
printtipwts <- matrix(0, ngr*ngc, narrays)
# Set up design matrix for array variance model
Z <- contr.sum(narrays)
spots <- 1:nspots
gridnum <- 1
for (gridr in 1:ngr) {
for (gridc in 1:ngc) {
# Intialise sub-array variances to zero
arraygammas <- rep(0, (narrays-1))
method <- match.arg(method,c("genebygene","reml"))
switch(method, genebygene = { # Estimate sub-array variances via gene-by-gene update algorithm
Zinfo <- 10*(narrays-nparams)/narrays*crossprod(Z, Z)
for(i in spots) {
if(!all(is.finite(arraygammas)))
stop("convergence problem at gene ", i, " in print-tip grid row ", gridr, ", column ", gridc, ": array weights not estimable")
vary <- exp(Z%*%arraygammas)
if(!is.null(weights)) { # combine spot weights with running weights
if(max(weights[i,], na.rm=TRUE) > 1) {
weights[i,] <- weights[i,]/max(weights[i,])
}
w <- as.vector(1/vary*weights[i,])
} else {
w <- as.vector(1/vary)
}
y <- as.vector(M[i,])
obs <- is.finite(y) & w!=0
if (sum(obs) > 1) {
if(sum(obs) == narrays) {
X <- design
} else { # remove missing/infinite values
X <- design[obs, , drop = FALSE]
y <- y[obs]
vary <- vary[obs]
Z2 <- Z[obs,]
}
out <- lm.wfit(X, y, w[obs])
d <- rep(0, narrays)
d[obs] <- w[obs]*out$residuals^2
s2 <- sum(d[obs])/out$df.residual
Q <- qr.Q(out$qr)
if(ncol(Q)!=out$rank)
Q <- Q[,-((out$rank+1):ncol(Q)),drop=FALSE]
h <- rep(1, narrays)
h[obs] <- rowSums(Q^2)
Agam <- crossprod(Z, (1-h)*Z)
Agam.del <- crossprod(t(rep(h[narrays], narrays-1)-h[1:(length(narrays)-1)]))
Agene.gam <- (Agam - 1/out$df.residual*Agam.del)
if(is.finite(sum(Agene.gam)) && sum(obs) == narrays) {
Zinfo <- Zinfo + Agene.gam
R <- chol(Zinfo)
Zinfoinv <- chol2inv(R)
zd <- d/s2 - 1 + h
Zzd <- crossprod(Z, zd)
gammas.iter <- Zinfoinv%*%Zzd
arraygammas <- arraygammas + gammas.iter
}
if(is.finite(sum(Agene.gam)) && sum(obs) < narrays && sum(obs) > 2) {
Zinfo <- Zinfo + Agene.gam
A1 <- (diag(1, sum(obs))-1/sum(obs)*matrix(1, sum(obs), sum(obs)))%*%Z2
A1 <- A1[-sum(obs),] # remove last row
R <- chol(Zinfo)
Zinfoinv <- chol2inv(R)
zd <- d/s2 - 1 + h
Zzd <- A1%*%crossprod(Z, zd)
Zinfoinv.A1 <- A1%*%Zinfoinv%*%t(A1)
alphas.old <- A1%*%arraygammas
alphas.iter <- Zinfoinv.A1%*%Zzd
alphas.new <- alphas.old + alphas.iter
Us <- rbind(diag(1, sum(obs)-1), -1)
Usalphas <- Us%*%(alphas.new-alphas.old)
Usgammas <- Z%*%arraygammas
Usgammas[obs] <- Usgammas[obs] + Usalphas
arraygammas <- Usgammas[1:(narrays-1)]
}
}
}
}, reml = { # Estimate sub-array variances via reml
# const <- narrays * log(2 * pi)
iter <- 0
dev <- 0
repeat {
# devold <- dev
# dev <- 0
iter <- iter + 1
zd <- matrix(0, narrays, 1)
sum1minush <- matrix(0, narrays, 1)
K <- matrix(0, nprobes, narrays)
for(i in spots) {
vary <- exp(Z%*%arraygammas)
if(!is.null(weights)) { # combine spot weights with running weights
if(max(weights[i,], na.rm=TRUE) > 1) {
weights[i,] <- weights[i,]/max(weights[i,])
}
w <- as.vector(1/vary*weights[i,])
} else {
w <- as.vector(1/vary)
}
y <- as.vector(M[i,])
obs <- is.finite(y) & w!=0
n <- sum(obs)
if (n > 0) {
if(n == narrays) {
X <- design
#Z2 <- Z
} else { # remove missing/infinite values
X <- design[obs, , drop = FALSE]
y <- y[obs]
vary <- vary[obs]
w <- w[obs]
const <- sum(obs) * log(2 * pi)
}
# cat(i)
out <- lm.wfit(X, y, w)
d <- rep(0, narrays)
d[obs] <- w*out$residuals^2
s2 <- sum(d[obs])/out$df.residual
Q <- qr.Q(out$qr)
if(ncol(Q)!=out$rank)
Q <- Q[,-((out$rank+1):ncol(Q)),drop=FALSE]
h <- rowSums(Q^2)
zd[obs] <- zd[obs] + d[obs]/s2 - 1 + h
sum1minush[obs,1] <- sum1minush[obs,1] + 1-h
K[i,][obs] <- as.vector(h[n]-h)
# dev <- dev + sum(d[obs]/vary) + sum(log(vary)) + const + 2 * log(prod(abs(diag(out$qr$qr))))
}
}
Zzd <- crossprod(Z, zd)
Zinfo <- diag(sum1minush[1:(narrays-1)]) + sum1minush[narrays] - crossprod(K[,-narrays])/out$df.residual # (narrays-nparams)
R <- chol(Zinfo)
Zinfoinv <- chol2inv(R)
gammas.iter <- Zinfoinv%*%Zzd
arraygammas <- arraygammas + gammas.iter
# arrayw <- drop(exp(Z %*% (-arraygammas)))
x2 <- crossprod(Zzd, gammas.iter) / narrays
if(trace)
cat("Iter =", iter, " X2 =", x2, " Print-tip grid row ", gridr,
" column ", gridc, " gammas: ", arraygammas, "\n")
if(!all(is.finite(arraygammas)))
stop("convergence problem at iteration ", iter, ": array weights not estimable")
# if (dev < devold - 1e-50)
# break
if (x2 < tol)
break
if (iter == maxiter) {
warning("Maximum iterations ", maxiter, " reached", sep="")
break
}
}
})
# matrix(rep(1/exp(Z%*%arraygammas), each=nspots), nprobes, narrays)
printtipwts[gridnum, ] <- drop(exp(Z %*% (-arraygammas)))
spots <- spots + nspots
# arrays <- arrays + narrays
gridnum <- gridnum + 1
# cat("\n")
}
}
# Make a matrix of print-tip weights for use in lmFit()
ngrids <- ngr*ngc
wts <- matrix(0, nspots*ngrids, narrays)
spots <- 1:nspots
for(i in 1:ngrids) {
for(j in 1:narrays) {
wts[spots,j] <- printtipwts[i,j]
}
spots <- spots + nspots
}
wts
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.