The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
linf is a lightweight R package for analysing compositional data through L-infinity (L∞) normalization and Dominant Community State Types (dCSTs).
Standard compositional approaches (CLR, ILR) map data into log-ratio coordinates, introducing complications with zeros and obscuring the dominant features that often drive biological variation. L∞ normalization takes a different path: divide each sample by its maximum, placing every observation on the boundary of the unit L∞ ball. The dominant feature — the one that achieves the maximum — defines a natural, parameter-free partition of samples into dominance sample sets.
At its core this is a rank-based analysis. Depth-1 dCSTs partition samples by the rank-1 (most abundant) feature. Depth-2 dCSTs refine each retained dominance-lineage using the rank-2 feature, and so on. This perspective connects dCSTs to one of the oldest branches of statistical methodology — rank analysis — while the L∞ geometry adds a principled compositional framework and a single, interpretable support threshold n₀.
This package accompanies: Gajer & Ravel (2025), A New Approach to Compositional Data Analysis using L∞-normalization with Applications to Vaginal Microbiome (arXiv:2503.21543).
# From GitHub (development version)
# install.packages("devtools")
devtools::install_github("pgajer/linf", build_vignettes = TRUE)or
# From CRAN
install.packages("linf")normalize.linf():
row-wise division by maximum, mapping each sample to the L∞ unit-ball
boundary.linf.cells(): rank-1 assignment per sample, returning
indices, labels, and level sets.linf.csts(): retain
dominance sample sets with support ≥ n₀, reassign rare
dominants by restricted argmax.refine.linf.csts(): depth-2+ dCSTs via successive rank
decomposition.linf.landmarks():
representative compositional profiles (endpoint max/min, mean) for each
dCST.filter.asv():
library-size and prevalence filtering for amplicon count matrices.asv.to.linf.csts():
counts → filter → normalise → truncated dCSTs in one call.library(linf)
set.seed(1)
# toy counts (samples × features)
S.counts <- matrix(rpois(10 * 3, 5), nrow = 10, ncol = 3,
dimnames = list(paste0("s", 1:10), c("A", "B", "C")))
# L∞ relatives (nonzero rows have max 1; zeros remain zero)
Z <- normalize.linf(S.counts)
apply(Z, 1, max)
#> returns 1 for nonzero rows, 0 for all-zero rows
# Dominant-feature assignments: indices + labels
cells <- linf.cells(Z)
table(cells$label, useNA = "ifany")
# Truncated dCSTs: retain states with at least n0 samples
res <- linf.csts(Z, n0 = 4)
table(res$cell.label, useNA = "ifany")The figure below illustrates depth-1 dCSTs in a bundled set of 766 gut microbiome samples from the American Gut Project (AGP). The subset was deliberately stratified to include every sample assigned to four selected uncommon dCSTs; the remaining slots are a seed-42 simple random sample from the eligible background. Phenotypes do not influence selection. The object is suitable for demonstrating the package workflow, but its phenotype frequencies, effect sizes, and p-values must not be interpreted as population estimates because inclusion probabilities differ by dCST.

The largest depth-1 dCSTs in this selected subset are
Bacteroides, Escherichia-Shigella, and
RARE_DOMINANT. The red bar marks
RARE_DOMINANT—samples whose rank-1 taxon does not form a
sufficiently supported dominance sample set at the chosen threshold.
See vignette("linf-intro") for the package-safe
demonstration. The full-analysis
source uses an independently selected 5,000-sample analysis cohort
and is maintained as a companion repository article rather than a
package vignette.
The package ships with two vignettes:
browseVignettes("linf")filter.asv,
normalize.linf).linf.cells() is invariant to positive row scaling
(counts vs relatives).max.col(..., ties.method = "first")).NA for both index and
label.The function name linf.cells() and cell.*
result fields are retained for backward compatibility. In prose, the
current nomenclature is dominance sample set at depth 1
and dominance-lineage for a retained hierarchical dCST
label.
If you use this package, please cite:
Gajer, P. & Ravel, J. (2025). A New Approach to Compositional Data Analysis using L∞-normalization with Applications to Vaginal Microbiome. arXiv preprint arXiv:2503.21543 [stat.CO]. doi: 10.48550/arXiv.2503.21543
BibTeX
@article{gajer2025linf,
title = {A New Approach to Compositional Data Analysis using
{$L^{\infty}$}-normalization with Applications to
Vaginal Microbiome},
author = {Gajer, Pawel and Ravel, Jacques},
year = {2025},
eprint = {2503.21543},
archivePrefix = {arXiv},
primaryClass = {stat.CO},
journal = {arXiv preprint arXiv:2503.21543},
doi = {10.48550/arXiv.2503.21543},
url = {https://arxiv.org/abs/2503.21543}
}MIT © 2025 Pawel Gajer. See LICENSE /
LICENSE.md. Bundled-data sources and upstream terms are
recorded in inst/DATA_PROVENANCE.md.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.