Suppose I want to combine voomWithQualityWeights
and duplicateCorrelation
. Would the modification of voomWithQualityWeights
below be the recommended approach? I only added lines for duplicateCorrelation
(based on using duplicateCorrelation with limma+voom for RNA-seq data) and included the correlation as part of the output list to be used with lmFit
later, but I wasn't sure about which set of weights to pass to each instance of duplicateCorrelation
:
- The array weights (
aw
, what I am currently using) - The voom observation-level weights (
v$weights
, the default whenweights = NULL
) - The product of the two
t(aw * t(v$weights))
Note: voomWithCorrelationAndWeights(..., ndups = 0)
(no blocking) is equivalent to voomWithQualityWeights()
with the addition of the correlation (value of 0) in the output.
voomWithCorrelationAndWeights <-
function(counts, design = NULL, lib.size = NULL, normalize.method = "none",
plot = FALSE, span = 0.5, var.design = NULL, var.group = NULL,
method = "genebygene", maxiter = 50, tol = 1e-05,
trace = FALSE, col = NULL,
# from duplicateCorrelation
ndups = 2, spacing = 1, trim = 0.15, block = NULL,
...)
{
if (plot) {
oldpar <- par(mfrow = c(1, 2))
on.exit(par(oldpar))
}
# Iter 1
v <- voom(counts, design = design, lib.size = lib.size,
normalize.method = normalize.method, plot = FALSE, span = span,
...)
aw <- arrayWeights(v, design = design, method = method,
maxiter = maxiter, tol = tol,
var.design = var.design, var.group = var.group)
dupecor <- duplicateCorrelation(v, design = design, block = block,
ndups = ndups, spacing = spacing, trim = trim,
weights = aw) # update v$weights or use aw here?
# Iter 2
v <- voom(counts, design = design, lib.size = lib.size,
normalize.method = normalize.method, plot = plot, span = span,
# Changes from first iteration
block = block, correlation = dupecor$consensus.correlation,
weights = aw,
...)
aw <- arrayWeights(v, design = design, method = method,
maxiter = maxiter, tol = tol, trace = trace,
var.design = var.design, var.group = var.group)
dupecor <- duplicateCorrelation(v, design = design, block = block,
ndups = ndups, spacing = spacing, trim = trim,
weights = aw) # same question as above
# Update weights and add correlation to output (needed for lmFit)
v$weights <- t(aw * t(v$weights))
v$targets$sample.weights <- aw
v$correlation <- dupecor$consensus.correlation
if (plot) {
barplot(aw, names = 1:length(aw), main = "Sample-specific weights",
ylab = "Weight", xlab = "Sample", col = col)
abline(h = 1, col = 2, lty = 2)
}
return(v)
}
Highly simplified version of how this function may be used:
# dge = DGEList object, design = design matrix, block = blocking factor,
# var.group = each level of this factor is assigned a different sample weight
v <- voomWithCorrelationAndWeights(dge, design = design,
block = block, var.group = var.group)
fit <- lmFit(v, design = design, block = block, correlation = v$correlation)
fit.smooth <- eBayes(fit)
Edit: added voom tag and changed counts
in last code chunk to dge
.
Thanks, Gordon! Exactly what I was looking for. I'm putting together a series of wrapper functions for some limma proteomics data analysis pipelines that my workplace commonly uses or is likely to use in the future, and this will simplify my (probably over-engineered) code quite a bit.
What sort of proteomics data?
Please be mindful that voom is designed for sequencing data and for RNA-seq in particular. We have never tested voom on proteomics data and I would not expect it to be ideal for that sort of data.
I apologize for the confusion. I meant that the wrapper functions will mainly handle TMT proteomics data, since that is what myself and colleagues encounter most often, but it will also include the ability to analyze RNA-Seq data. It will be similar to what I've done in this limma_full function, but only the
MArrayLM
object fromeBayes
will be output, and I will be including more robust checks for user input, among other improvements. The portion of the code that analyzes RNA-Seq data follows what is outlined in Law et al. (2018), but I will switch to usingvoomLmFit
.