getNullDistribution_BSmooth.tstat <- function(BSseq, idxMatrix1, idxMatrix2,
estimate.var, local.correct,
cutoff, stat, maxGap, mc.cores = 1) {
stopifnot(nrow(idxMatrix1) == nrow(idxMatrix2))
message(sprintf("[getNullDistribution_BSmooth.tstat] performing %d permutations\n", nrow(idxMatrix1)))
nullDist <- mclapply(1:nrow(idxMatrix1), function(ii) {
ptime1 <- proc.time()
BS.tstat <- BSmooth.tstat(BSseq, estimate.var = estimate.var,
group1 = idxMatrix1[ii,],
group2 = idxMatrix2[ii,],
local.correct = local.correct, maxGap = 10^8,
verbose = FALSE)
dmrs0 <- dmrFinder(BS.tstat, stat = stat, cutoff = cutoff, maxGap = maxGap)
ptime2 <- proc.time()
stime <- (ptime2 - ptime1)[3]
message(sprintf("[getNullDistribution_BSmooth.tstat] completing permutation %d in %.1f sec\n", ii, stime))
dmrs0
}, mc.cores = min(nrow(idxMatrix1), mc.cores), mc.preschedule = FALSE)
nullDist
}
getNullDistribution_BSmooth.fstat <- function(BSseq,
idxMatrix,
design, contrasts,
coef = NULL, cutoff,
maxGap.sd, maxGap.dmr,
mc.cores = 1) {
message(sprintf("[getNullDistribution_BSmooth.fstat] performing %d permutations\n",
nrow(idxMatrix)))
# NOTE: Using mc.preschedule = TRUE
# TODO: Need some protection for when a core(s) error, otherwise nullDist
# contains a mixture of data frame, NULL, and try-error objects
# (which will subesequently break when passed to getFWER.fstat())
nullDist <- mclapply(seq_len(nrow(idxMatrix)), function(ii) {
ptime1 <- proc.time()
# NOTE: More efficient to permute design matrix using idxMatrix[ii, ] than
# permute the raw data with BSseq[, idxMatrix[ii, ]]
bstat <- BSmooth.fstat(BSseq, design = design[idxMatrix[ii, ], ],
contrasts = contrasts)
bstat <- smoothSds(bstat, maxGap = maxGap.sd)
bstat <- computeStat(bstat, coef = coef)
dmrs0 <- dmrFinder(bstat, cutoff = cutoff, maxGap = maxGap.dmr)
ptime2 <- proc.time()
stime <- (ptime2 - ptime1)[3]
message(sprintf("[getNullDistribution_BSmooth.fstat] completing permutation %d in %.1f sec\n", ii, stime))
dmrs0
}, mc.cores = min(nrow(idxMatrix), mc.cores), mc.preschedule = TRUE)
nullDist
}
permuteAll <- function(nperm, design) {
message(sprintf("[permuteAll] performing %d unrestricted permutations of the design matrix\n", nperm))
CTRL <- how(nperm = nperm)
# NOTE: shuffleSet() returns a nperm * nrow(design) matrix of permutations
idxMatrix <- shuffleSet(n = nrow(design), control = CTRL)
}
getNullBlocks_BSmooth.tstat <- function(BSseq, idxMatrix1, idxMatrix2, estimate.var = "same",
mc.cores = 1) {
getNullDistribution_BSmooth.tstat(BSseq = BSseq, idxMatrix1 = idxMatrix1,
idxMatrix2 = idxMatrix2, local.correct = FALSE,
estimate.var = estimate.var,
cutoff = c(-2,2), stat = "tstat", maxGap = 10000,
mc.cores = mc.cores)
}
getNullDmrs_BSmooth.tstat <- function(BSseq, idxMatrix1, idxMatrix2, estimate.var = "same",
mc.cores = 1) {
getNullDistribution_BSmooth.tstat(BSseq = BSseq, idxMatrix1 = idxMatrix1,
idxMatrix2 = idxMatrix2, local.correct = TRUE,
estimate.var = estimate.var,
cutoff = c(-4.6,4.6), stat = "tstat.corrected", maxGap = 300,
mc.cores = mc.cores)
}
subsetDmrs <- function(xx) {
if(is.null(xx) || is(xx, "try-error"))
return(NULL)
out <- xx[ xx[,"n"] >= 3 & abs(xx[, "meanDiff"]) > 0.1 &
xx[, "invdensity"] <= 300, ]
if(nrow(out) == 0)
return(NULL)
out
}
subsetBlocks <- function(xx) {
if(is.null(xx) || is(xx, "try-error"))
return(NULL)
out <- subset(xx, width >= 10000)
if(nrow(out) == 0)
return(NULL)
out
}
getFWER <- function(null, type = "blocks") {
reference <- null[[1]]
null <- null[-1]
null <- null[!sapply(null, is.null)]
better <- sapply(1:nrow(reference), function(ii) {
# meanDiff <- abs(reference$meanDiff[ii])
areaStat <- abs(reference$areaStat[ii])
width <- reference$width[ii]
n <- reference$n[ii]
if (type == "blocks") {
out <- sapply(null, function(nulldist) {
# any(abs(nulldist$meanDiff) >= meanDiff &
# nulldist$width >= width)
any(abs(nulldist$areaStat) >= areaStat &
nulldist$width >= width)
})
}
if (type == "dmrs") {
out <- sapply(null, function(nulldist) {
# any(abs(nulldist$meanDiff) >= meanDiff &
# nulldist$n >= n)
any(abs(nulldist$areaStat) >= areaStat &
nulldist$n >= n)
})
}
sum(out)
})
better
}
# NOTE: Identical to getFWER() except uses areaStat rather than meanDiff
# to compare regions.
getFWER.fstat <- function(null, type = "blocks") {
reference <- null[[1]]
null <- null[-1]
null <- null[!sapply(null, is.null)]
# TODO: Will break if null == list(), which can occur in practice (although
# rarely).
better <- sapply(seq_len(nrow(reference)), function(ii) {
# meanDiff <- abs(reference$meanDiff[ii])
areaStat <- abs(reference$areaStat[ii])
width <- reference$width[ii]
n <- reference$n[ii]
if (type == "blocks") {
out <- vapply(null, function(nulldist) {
# any(abs(nulldist$meanDiff) >= meanDiff &
# nulldist$width >= width)
any(abs(nulldist$areaStat) >= areaStat &
nulldist$width >= width)
}, logical(1L))
}
if (type == "dmrs") {
out <- vapply(null, function(nulldist) {
# any(abs(nulldist$meanDiff) >= meanDiff &
# nulldist$n >= n)
any(abs(nulldist$areaStat) >= areaStat &
nulldist$n >= n)
}, logical(1L))
}
sum(out)
})
better
}
# TODO: Simplify makeIdxMatrix() by using permute package
makeIdxMatrix <- function(group1, group2, testIsSymmetric = TRUE, includeUnbalanced = TRUE) {
groupBoth <- c(group1, group2)
idxMatrix1 <- NULL
subsetByMatrix <- function(vec, mat) {
apply(mat, 2, function(xx) vec[xx])
}
combineMat <- function(mat1, mat2) {
tmp <- lapply(1:nrow(mat1), function(ii) {
t(apply(mat2, 1, function(xx) { c(mat1[ii,], xx) }))
})
do.call(rbind, tmp)
}
if(length(group1) == 1 && length(group1) == 1) {
if(testIsSymmetric)
idxMatrix1 <- as.matrix(group1)
else
idxMatrix1 <- as.matrix(c(group1, group2))
}
if(length(group1) == 2 && length(group2) == 2) {
if(testIsSymmetric) {
idxMatrix1 <- rbind(group1,
combineMat(matrix(group1[1], ncol = 1),
matrix(group2, ncol = 1)))
} else {
idxMatrix1 <- rbind(group1, group2,
combineMat(matrix(group1, ncol = 1), matrix(group2, ncol = 1)))
}
}
if(length(group1) == 3 && length(group1) == 3) {
if(testIsSymmetric) {
idxMatrix1 <- rbind(group1,
combineMat(subsetByMatrix(group1, combinations(3,2)),
as.matrix(group2, ncol = 1)))
} else {
idxMatrix1 <- rbind(group1, group2,
combineMat(subsetByMatrix(group1, combinations(3,2)),
as.matrix(group2, ncol = 1)),
combineMat(as.matrix(group1, ncol = 1),
subsetByMatrix(group2, combinations(3,2))))
}
}
if(length(group1) == 4 && length(group1) == 4) {
if(testIsSymmetric) {
idxMatrix1 <- rbind(group1,
combineMat(subsetByMatrix(group1, combinations(3,2)),
subsetByMatrix(group2, combinations(4,2))))
} else {
idxMatrix1 <- rbind(group1, group2,
combineMat(subsetByMatrix(group1, combinations(4,2)),
subsetByMatrix(group2, combinations(4,2))))
}
if(includeUnbalanced) {
newMatrix <- combineMat(subsetByMatrix(group1, combinations(4,3)),
as.matrix(group2, ncol = 1))
idxMatrix1 <- rbind(idxMatrix1, newMatrix)
}
if(includeUnbalanced && !testIsSymmetric) {
newMatrix <- combineMat(as.matrix(group1, ncol = 1),
subsetByMatrix(group2, combinations(4,3)))
idxMatrix1 <- rbind(idxMatrix1, newMatrix)
}
}
if(length(group1) == 5 && length(group1) == 5) {
if(testIsSymmetric) {
idxMatrix1 <- rbind(group1,
combineMat(subsetByMatrix(group1, combinations(5, 3)),
subsetByMatrix(group2, combinations(5, 2))))
} else {
idxMatrix1 <- rbind(group1, group2,
combineMat(subsetByMatrix(group1, combinations(5, 3)),
subsetByMatrix(group2, combinations(5, 2))),
combineMat(subsetByMatrix(group1, combinations(5, 2)),
subsetByMatrix(group2, combinations(5, 3))))
}
if(includeUnbalanced) {
idxMatrix1 <- rbind(idxMatrix1,
combineMat(subsetByMatrix(group1, combinations(5,4)),
as.matrix(group2, ncol = 1)))
}
if(includeUnbalanced && !testIsSymmetric) {
idxMatrix1 <- rbind(idxMatrix1,
combineMat(as.matrix(group1, ncol = 1),
subsetByMatrix(group2, combinations(5,4))))
}
}
if(length(group1) == 6 && length(group1) == 6) {
if(testIsSymmetric) {
idxMatrix1 <- rbind(group1,
combineMat(subsetByMatrix(group1, combinations(5,3)),
subsetByMatrix(group2, combinations(6,3))))
} else {
idxMatrix1 <- rbind(group1, group2,
combineMat(subsetByMatrix(group1, combinations(6,3)),
subsetByMatrix(group2, combinations(6,3))))
}
if(includeUnbalanced) {
newMatrix1 <- combineMat(subsetByMatrix(group1, combinations(6,4)),
subsetByMatrix(group2, combinations(6,2)))
newMatrix2 <- combineMat(subsetByMatrix(group1, combinations(6,5)),
as.matrix(group2, ncol = 1))
idxMatrix1 <- rbind(idxMatrix1, newMatrix1, newMatrix2)
}
if(includeUnbalanced && !testIsSymmetric) {
newMatrix1 <- combineMat(subsetByMatrix(group1, combinations(6,2)),
subsetByMatrix(group2, combinations(6,4)))
newMatrix2 <- combineMat(as.matrix(group1, ncol = 1),
subsetByMatrix(group2, combinations(6,5)))
idxMatrix1 <- rbind(idxMatrix1, newMatrix1, newMatrix2)
}
}
if(is.null(idxMatrix1))
stop("unable to handle this combination of 'group1', 'group2' and 'testIsSymmetric'")
rownames(idxMatrix1) <- NULL
idxMatrix2 <- do.call(rbind, lapply(1:nrow(idxMatrix1), function(ii) {
setdiff(groupBoth, idxMatrix1[ii,])
}))
return(list(idxMatrix1 = idxMatrix1, idxMatrix2 = idxMatrix2))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.