<p>You're basically subtracting a constant per-gene per-level. The relevant portion of the code is:</p>
<pre><code>fit &lt;- lmFit(x,cbind(design,X.batch),...)
beta &lt;- fit$coefficients[,-(1:ncol(design)),drop=FALSE]
beta[is.na(beta)] &lt;- 0
as.matrix(x) - beta %*% t(X.batch)
</code></pre>
<p>where <code>x</code> is your input matrix, <code>design</code> is the design matrix and <code>X.batch</code> is the matrix of batch and covariates. So you're fitting your data with the combined batch/design matrix (line 1), extracting out the batch coefficients (line 2), and subtracting out the expected effect (line 4). This is simple enough and remarkably effective for its intended use. You can get a bit fancier by using PCA or something else to instead allow individual samples to be more/less affected by a batch-effect, but added complexity has its own issues.</p>

CC BY-SA 4.0
2021-08-19T21:59:55.880Z
2021-08-19T21:59:55.880Z
Devon Ryan
<p>What does removing a batch effect (e.g. with <code>limma::removeBatchEffect</code>) assume about the batch effect?</p>
<p>Does it assume simply a constant batch effect for each level?
E.g. if the levels are</p>
<pre><code>Date1
Date2
Date3
</code></pre>
<p>Then one constant will be subtracted from all samples on Date3, another constant from all samples of Date2 and so on?</p>
<p>Or is it more complicated?</p>

<limma><batch-effects>
Assumptions of batch effect removal
# Assumptions of batch effect removal

(Asked by: username_0 on 2021-08-19)

What does removing a batch effect (e.g. with limma::removeBatchEffect) assume about the batch effect?
Does it assume simply a constant batch effect for each level?
E.g. if the levels are
Date1
Date2
Date3

Then one constant will be subtracted from all samples on Date3, another constant from all samples of Date2 and so on?
Or is it more complicated?

**Tags:** limma, batch-effects

---

## 1 answers

### Answer by username_1 on 2021-08-19. Score: 1 | Accepted answer

You're basically subtracting a constant per-gene per-level. The relevant portion of the code is:
fit <- lmFit(x,cbind(design,X.batch),...)
beta <- fit$coefficients[,-(1:ncol(design)),drop=FALSE]
beta[is.na(beta)] <- 0
as.matrix(x) - beta %*% t(X.batch)

where x is your input matrix, design is the design matrix and X.batch is the matrix of batch and covariates. So you're fitting your data with the combined batch/design matrix (line 1), extracting out the batch coefficients (line 2), and subtracting out the expected effect (line 4). This is simple enough and remarkably effective for its intended use. You can get a bit fancier by using PCA or something else to instead allow individual samples to be more/less affected by a batch-effect, but added complexity has its own issues.


---

