Skip to contents

WHAT: for each batch, build the monotone map that carries that batch's quantiles onto the pooled reference quantiles, and apply it.

Usage

align_quantiles(
  x,
  batch,
  probs = seq(0, 1, length.out = 101),
  goal = c("batch_mean", "cells"),
  goal_batches = NULL
)

Arguments

x

numeric vector for one marker, across all cells

batch

batch label per cell

probs

quantile grid used to build the map

goal

"batch_mean" (default) or "cells"; see above.

goal_batches

batches the goal is built from, or NULL for every batch; see align_within_groups() for why it is restricted.

Value

numeric vector, corrected

Details

WHY MONOTONE INTERPOLATION AND NOT A SHIFT OR A Z-SCORE: a shift corrects the location of a distribution and leaves its shape, so a batch whose negative population is wider stays wider and its gate still lands somewhere else. A z-score assumes the spread is meaningful on both sides of zero, which is false for a bimodal marker where the two modes have different variances. Matching quantiles corrects the shape too, and because the map is monotone it preserves the ORDER of cells within a batch – the property that stops a correction from inventing structure.

THE GOAL IS THE MEAN OF THE BATCHES' QUANTILES, as CytoNorm's is (Van Gassen et al. 2020), not the quantiles of every cell pooled. A pooled goal weights each batch by its cell count, so the batch holding most cells sets the scale everything is mapped onto, and when the batches differ in which samples they hold the goal carries that imbalance into every batch. goal = "cells" keeps the pooled form.