Nothing
#' one-round genome scan with specified cofactor(s)
#'
#' @importFrom stats coef pchisq model.matrix
#' @keywords internal
scanQTL <- function(modDat,
map,
markers,
parents,
QTLwindow = 10,
cof = NULL,
Usc = NULL,
trait = NULL,
maxIter = 100,
se = FALSE,
parallel = FALSE,
verbose = FALSE) {
## Get info from input.
nPar <- length(parents)
nGeno <- nrow(modDat)
nCross <- length(unique(modDat[["cross"]]))
## Create general model matrices.
y <- modDat[[trait]]
X <- spam::as.spam(model.matrix(if (nCross > 1) ~cross else ~ 1,
data = modDat))
lRinv <- constructRinv(modDat, residual = ~cross, weights = 1)
## Fit NULL model with all cofactors.
Z0 <- do.call(spam::cbind.spam, lapply(X = cof, FUN = function(mrk) {
markers[, mrk, ]
}))
## Fit models for each marker.
chrs <- unique(map[["chr"]])
`%op%` <- getOper(parallel && foreach::getDoParRegistered())
scanFull <- foreach::foreach(i = seq_along(chrs)) %op% {
UscChr <- Usc[[i]]
nEigChr <- ncol(UscChr)
## Add genotype.
lGinv0 <- lapply(X = seq_along(cof), FUN = function(i) {
spam::diag.spam(x = c(rep(0, nPar * (i - 1)),
rep(1, nPar),
rep(0, nPar * (length(cof) - i) +
if (!is.null(Usc)) nEigChr else 0)))
})
names(lGinv0) <- cof
if (!is.null(UscChr)) {
ZChr <- spam::cbind.spam(Z0, UscChr)
lGinv1 <- spam::diag.spam(x = c(rep(0, times = length(cof) * nPar),
rep(1, nEigChr)))
LGinvChr <- c(lGinv0, list(K = lGinv1))
} else {
ZChr <- Z0
LGinvChr <- lGinv0
}
## Fit NULL model with all cofactors.
fitModNULL <- sparseMixedModels(y = y, X = X, Z = ZChr,
lRinv = lRinv, lGinv = LGinvChr,
tolerance = 1e-3)
chrMrk <- rownames(map)[map[["chr"]] == chrs[i]]
QTLRegion <- setNames(logical(length = length(chrMrk)), chrMrk)
minlog10p <- setNames(numeric(length = length(chrMrk)), chrMrk)
effects <- seEffects <- matrix(nrow = length(chrMrk), ncol = nPar,
dimnames = list(chrMrk, parents))
for (scanMrk in chrMrk) {
## Get cofactors for current markers.
cofMrk <- selectCofactors(map = map,
marker = scanMrk,
cofactors = cof,
QTLwindow = QTLwindow)
selMrk <- c(scanMrk, cofMrk)
ZMrk <- do.call(spam::cbind.spam, lapply(X = selMrk, FUN = function(mrk) {
markers[, mrk, ]
}))
lGinvMrk <- lapply(X = seq_along(selMrk), FUN = function(i) {
spam::diag.spam(x = c(rep(0, nPar * (i - 1)),
rep(1, nPar),
rep(0, nPar * (length(selMrk) - i) +
if (!is.null(UscChr)) nEigChr else 0)))
})
names(lGinvMrk) <- selMrk
if (!is.null(UscChr)) {
ZMrk <- spam::cbind.spam(ZMrk, UscChr)
lGinv1Mrk <- spam::diag.spam(x = c(rep(0, times = length(selMrk) * nPar),
rep(1, nEigChr)))
lGinvMrk <- c(lGinvMrk, list(K = lGinv1Mrk))
}
## Fit model for current marker.
fitModMrk <- sparseMixedModels(y = y, X = X, Z = ZMrk,
lRinv = lRinv, lGinv = lGinvMrk,
tolerance = 1e-3)
## Compute change in deviance.
dev <- 2 * fitModMrk$logL - 2 * fitModNULL$logL
## Refit NULL model only if cofactors differ for current marker.
if (length(cofMrk) != length(cof)) {
## Fit NULL model with restricted cofactors.
ZMrk2 <- do.call(spam::cbind.spam, lapply(X = cofMrk,
FUN = function(mrk) {
markers[, mrk, ]
}))
lGinvMrk2 <- lapply(X = seq_along(cofMrk), FUN = function(i) {
spam::diag.spam(x = c(rep(0, nPar * (i - 1)),
rep(1, nPar),
rep(0, nPar * (length(cofMrk) - i) +
if (!is.null(UscChr)) nEigChr else 0)))
})
names(lGinvMrk2) <- cofMrk
if (!is.null(UscChr)) {
ZMrk2 <- cbind(ZMrk2, UscChr)
lGinv1Mrk2 <- spam::diag.spam(x = c(rep(0, times = length(cofMrk) * nPar),
rep(1, nEigChr)))
lGinvMrk2 <- c(lGinvMrk2, list(K = lGinv1Mrk2))
}
fitModCof <- sparseMixedModels(y = y, X = X, Z = ZMrk2,
lRinv = lRinv, lGinv = lGinvMrk2,
tolerance = 1e-3)
dev <- 2 * fitModMrk$logL - 2 * fitModCof$logL
}
QTLRegion[scanMrk] <- length(cofMrk) != length(cof)
minlog10p[scanMrk] <- min(-log10(0.5 * pchisq(dev, 1,
lower.tail = FALSE)), 300)
effects[scanMrk, ] <- fitModMrk$a[(1 + nCross):(length(parents) + nCross)]
if (se) {
Cinv <- spam::solve.spam(fitModMrk$C)
Dg <- spam::spam(x = 0, nrow = nPar, ncol = nrow(fitModMrk$C))
I <- spam::diag.spam(1, nPar)
J <- spam::spam(x = 1 / nPar, nrow = nPar, ncol = nPar)
Dg[1:nPar, (nCross + 1):(nCross + nPar)] <- I - J
seEffects[scanMrk, ] <-
as.vector(sqrt(spam::diag.spam(Dg %*% Cinv %*% t(Dg))))
}
}
list(QTLRegion, minlog10p, effects, seEffects)
}
QTLRegion <- do.call(c, lapply(X = scanFull, FUN = `[[`, 1))
minlog10p <- do.call(c, lapply(X = scanFull, FUN = `[[`, 2))
effects <- do.call(rbind, args = lapply(X = scanFull, FUN = `[[`, 3))
seEffects <- do.call(rbind, args = lapply(X = scanFull, FUN = `[[`, 4))
dimnames(effects) <- list(rownames(map), paste0("eff_", parents))
dimnames(seEffects) <- list(rownames(map), paste0("se_eff_", parents))
scanRes <- data.table::data.table(trait = trait,
snp = rownames(map),
map,
pValue = 10 ^ -minlog10p,
effects,
seEffects,
minlog10p = minlog10p,
QTLRegion = QTLRegion)
return(scanRes)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.