Why Transform Library-Scaled Counts?
A count of 8 does not mean the same relative abundance in a cell with a library of 10,000 counts as it does in a cell with a library of 20,000. Library scaling first puts counts on a common reference scale; a log1p transformation then compresses the resulting range. The transformation is convenient for describing and visualizing expression, but its values depend on the scale and pseudocount chosen.
The calculation has two distinct steps: divide a gene count by its cell’s size factor and multiply by a reference scale, then apply a logarithm with a pseudocount. Keeping these steps explicit makes it easier to see what a transformed value means and to avoid confusing it with either a raw count or a count-model response.
For total-count scaling, one possible size factor is the observed library total \(L_i\), and a common reference scale is \(a=10{,}000\). Then \(r_{ig}=10{,}000Y_{ig}/L_i\), and the usual calculation is \(\log(1+10{,}000Y_{ig}/L_i)\). Other positive size factors can be used in the same formula; their interpretation depends on how they were estimated and scaled.
The size factors must be positive, and counts must be nonnegative. The intended comparison also assumes that the size factors provide a suitable correction for differences in sequencing exposure for the target being studied. A log transformation cannot repair an unsuitable normalization. No particular probability distribution for counts is needed to calculate these transformed values, but the transformation itself does not make normalized values Gaussian or remove all differences in variability.
Worked Example: Calculating Library-Scaled log1p Values
Suppose the reference scale is \(a=10{,}000\), the pseudocount is \(p=1\), and two hypothetical cells have library totals of 20,000 and 10,000. A gene has counts 8 and 4 in those cells, respectively.
For the first cell, the scaled value is \(r=10{,}000(8)/20{,}000=4\). Its log1p value is
For the second cell, \(r=10{,}000(4)/10{,}000=4\), so its value is also \(\log(5)\approx1.609\). The raw counts differ, but the counts are equal relative to these library totals under this scaling. A gene with count zero in either cell has \(r=0\) and \(z=\log(1)=0\).
What the Pseudocount Changes
The pseudocount controls the scale at which small normalized values begin to rise on the log scale. It is part of the transformation, not an estimate of an unobserved count. With \(p=1\), a normalized value of 1 maps to \(\log(2)\); with a larger \(p\), the same value maps closer to zero. Because \(p\) is in normalized-value units, changing the reference scale without changing \(p\) also changes the effective transformation.
Worked Example: Comparing Pseudocounts at Zero and Low Values
Consider normalized values \(r=0\), \(0.2\), \(1\), and \(10\). Calculate \(g_p(r)=\log(1+r/p)\) using pseudocounts \(p=0.1\), \(1\), and \(5\).
| Normalized value \(r\) | \(p=0.1\) | \(p=1\) | \(p=5\) |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0.2 | \(\log(3)\approx1.099\) | \(\log(1.2)\approx0.1823\) | \(\log(1.04)\approx0.03922\) |
| 1 | \(\log(11)\approx2.398\) | \(\log(2)\approx0.6931\) | \(\log(1.2)\approx0.1823\) |
| 10 | \(\log(101)\approx4.615\) | \(\log(11)\approx2.398\) | \(\log(3)\approx1.099\) |
For instance, at \(r=0.2\) and \(p=5\), \(1+r/p=1+0.2/5=1.04\), giving \(\log(1.04)\approx0.03922\). Every zero remains zero. At positive values, a larger pseudocount gives a smaller transformed value, with especially noticeable changes near zero.
The denominator is positive. Thus, for fixed \(r\geq0\), increasing \(p\) makes \(g_p(r)\) nonincreasing: the derivative is zero when \(r=0\), and strictly negative when \(r>0\). In particular, all positive \(p\) give \(g_p(0)=0\); the transformed zero does not decrease below zero. Also, for fixed \(p>0\), \(g_p(r)\) increases with \(r\), since its derivative with respect to \(r\) is \(1/(p+r)>0\). These facts explain both zero preservation and why a common pseudocount preserves the ordering of positive normalized values.
Comparisons Across Cells and Order of Operations
If the same reference scale and pseudocount are used for every cell, the transformation is a strictly increasing function of the scaled value \(r\). Therefore, for two cells \(i\) and \(j\), \(r_{ig}<r_{jg}\) implies \(z_{ig}<z_{jg}\), and equal scaled values give equal transformed values. The pseudocount changes the numerical distances between values, not their ordering. In particular, the transform does not make the result independent of size factors: those factors determine \(r\) before the logarithm is applied.
Worked Example: Equal Relative Values with Different Library Sizes
Take \(a=10{,}000\), \(p=1\), and two hypothetical cells. Cell A has library total 10,000 and gene count 5; cell B has library total 20,000 and gene count 10.
For A, \(r_A=10{,}000(5)/10{,}000=5\), and \(z_A=\log(1+5)=\log(6)\approx1.792\). For B, \(r_B=10{,}000(10)/20{,}000=5\), and \(z_B=\log(1+5)=\log(6)\approx1.792\). The larger raw count in B does not produce a larger transformed value because the library total is also larger.
The order of operations matters. If instead one adds a pseudocount of one raw count before scaling, A gives \(\log(1+10{,}000(5+1)/10{,}000)=\log(7)\approx1.946\), whereas B gives \(\log(1+10{,}000(10+1)/20{,}000)=\log(6.5)\approx1.872\). The two cells had equal scaled values before this raw-count addition, but the added count contributes different amounts after scaling. To use one common pseudocount in normalized-value units, scale first and then calculate \(\log(1+r/p)\).
Another common convention is to take a logarithm with base 2 rather than the natural logarithm. For any positive argument, \(\log_2(x)=\log(x)/\log(2)\), so this changes the numerical values by a constant multiplier but not their ordering. The base and pseudocount must nevertheless be reported when values are compared or reproduced.
Alternatives, Diagnostics, and Limitations
Log-normalized values are useful for visualization and descriptive comparisons, but they are not raw counts and are not a substitute for the count likelihood and offset approach used in count models. The latter retains count-scale observations while accounting for exposure in the model; log-normalized values are a transformed scale for summaries or exploratory displays. Total-count scaling, counts-per-million scaling, and other size-factor choices can all feed into a log transform, but they need not yield identical scaled values.
A practical diagnostic is to recompute a small set of values directly from counts, size factors, scale, and pseudocount. Check that zeros remain zero, that equal scaled values produce equal transformed values, and that positive values retain their ordering when the same \(p\) is used. Plot or tabulate values near zero as well as larger values: a large \(p\) can make low positive values look very similar to zero, while a small \(p\) can spread those low values more widely.
The transformation also compresses differences at larger values. Its slope with respect to \(r\) is \(1/(p+r)\), which declines as \(r\) increases. Thus equal increments in normalized value do not correspond to equal increments on the log scale. This compression is useful for displays with a wide range, but transformed differences should not be read as count differences or as fold changes without specifying the scale and comparison being made.
A frequent error is to say that increasing the pseudocount makes every transformed value smaller. The correct statement is that, for fixed \(r\geq0\), the transformed value is nonincreasing as \(p\) increases and is strictly smaller only when \(r>0\). At zero it is unchanged. Another error is to add a pseudocount to raw counts and assume it has the same effect in every cell after library scaling; as the preceding calculation shows, that addition is rescaled by each cell’s size factor.
Check Your Understanding
Try each problem, then compare your work with the solutions below.
- With reference scale 10,000, size factor 25,000, count 15, and \(p=1\), calculate the scaled and log1p values.
- For fixed normalized value \(r=0\), what happens to \(g_p(r)\) as \(p\) increases? What about \(r=2\)?
- Two cells have the same scaled value \(r=3\), but different raw counts and size factors. If both use \(p=1\), must their log-normalized values match? Explain.
- Why can adding one to each raw count before scaling fail to preserve equality between two cells that have equal scaled values?
Solutions. (1) The scaled value is \(r=10{,}000(15)/25{,}000=6\); the log1p value is \(\log(1+6)=\log(7)\approx1.946\). (2) At \(r=0\), \(g_p(0)=\log(1)=0\) for every \(p>0\). At \(r=2\), the derivative \(-2/[p(p+2)]\) is negative, so the value strictly decreases as \(p\) increases. (3) Yes. Each value is \(\log(1+3/1)=\log(4)\approx1.386\), because the common transformation uses the scaled value, not the raw count alone. (4) A raw-count addition is divided by each cell’s size factor during scaling, so it contributes different amounts when size factors differ. The resulting scaled values, and hence their logarithms, can differ.