# ADAPT Tutorial

# Introduction

This is the tutorial for `ADAPT` (analysis of microbiome differential abundance analysis by pooling Tobit models). Differential abundance analysis (DAA) is one of the fundamental steps in microbiome research.1 The metagenomics count data have excessive zeros and are compositional, causing challenges for detecting microbiome taxa whose abundances are associated with different conditions. `ADAPT` overcomes these challenges differently from other DAA methods. First, `ADAPT` treats zero counts as left censored observations and apply Tobit models which are censored regressions2 for modeling the log count ratios. Second, `ADAPT` has an innovative and theoretically justified way of finding non-differentially abundant taxa as reference taxa. It then applies Tobit models to log count ratios between individual taxa and the summed counts of reference taxa to identify differentially abundant taxa. The overall workflow is presented in the graph below.

Workflow of ADAPT

There are two ways to install the package, either through GitHub or Bioconductor.

    # install through GitHub
    if(!require("ADAPT")) BiocManager::install("mkbwang/ADAPT", build_vignettes = TRUE)

    # install through Bioconductor
    if(!require("ADAPT")) BiocManager::install("ADAPT", version="devel",
                                               build_vignettes = TRUE)

# Main function `adapt`

The main function `adapt` takes in a phyloseq3 object that needs to have at least a count table and a sample metadata. The metadata must contain one variable that represents the condition to test on. We currently allow binary and continuous conditions. If there are more than two groups for the condition variable, the user may single out one group to compare with all the others for DAA. `ADAPT` allows adjusting for extra covariates. There are eight arguments in the `adapt` function:

1. `input_data` is the phyloseq object with the count matrix and metadata. This argument is required.
2. `cond.var` is the variable in the metadata that represents the condition to test on. This argument is required.
3. `base.cond` is the group that the user is interested in comparing against other groups. This argument is only needed if the condition is categorical.
4. `adj.var` contains the covariates to adjust for. It can be empty or be a vector of variable names.
5. `censor` is the value to censor at for all the zero counts. By default the zeros are censored at one.
6. `prev.filter` is the threshold for filtering out rare taxa. By default taxa with prevalence lower than 0.05 are filtered out before analysis.
7. `depth.filter` is the threshold for filtering out samples with low sequencing depths. The default threshold is 1000 reads.
8. `alpha` is the cutoff for the Benjamini-hochberg adjusted p-values to decide differentially abundant taxa. The default is 0.05.

The `ADAPT` package contains two metagenomics datasets from an early childhood dental caries study.4 One corresponds to 16S rRNA sequencing of 161 saliva samples collected from 12-month-old infants (`ecc_saliva`). The other corresponds to shotgun metagenomic sequencing of 30 plaque samples collected from kids between 36 and 60 months old (`ecc_plaque`). In this vignette let’s use the saliva data to find out differentially abundant taxa between kids who developed early childhood caries (ECC) after 36 months old and those who didn’t. Besides the main variable `CaseStatus`, there is another variable `Site` representing the site where each sample was collected. Both variables are discrete and contain two categories each.

    library(ADAPT)
    data(ecc_saliva)

We can run `adapt` with or without covariate adjustment. The returned object is a customized S4-type object with slots corresponding to analysis name, reference taxa, differentially abundant taxa, detailed analysis results (a dataframe) and input phyloseq object.

    saliva_output_noadjust <- adapt(input_data=ecc_saliva, cond.var="CaseStatus", base.cond="Control")
    #> Choose 'Control' as the baseline condition
    #> 155 taxa and 161 samples being analyzed...
    #> Selecting Reference Set... 77 taxa selected as reference
    #> 27 differentially abundant taxa detected
    saliva_output_adjust <- adapt(input_data=ecc_saliva, cond.var="CaseStatus", base.cond="Control", adj.var="Site")
    #> Choose 'Control' as the baseline condition
    #> 155 taxa and 161 samples being analyzed...
    #> Selecting Reference Set... 77 taxa selected as reference
    #> 28 differentially abundant taxa detected

The `Site` is not a confounding variable, therefore the DAA results only differ by one taxon.

# Explore Analysis Results

We have developed two utility functions for result exploration. `summary` returns a dataframe with the estimated log10 abundance fold changes, hypothesis test p-values and taxonomy (if provided in the phyloseq object). The user can choose to return results of all the taxa, the differentially abundant taxa only or the reference taxa only through the `select` variable (“all”, “da” or “ref”). We choose to return the results of only the DA taxa below.

    DAtaxa_result <- summary(saliva_output_noadjust, select="da")
    #> Differential abundance analysis for CaseStatus (Case VS Control)
    #> 155 taxa and 161 samples analyzed
    #> 77 taxa are selected as reference and 27 taxa are differentially abundant

    head(DAtaxa_result)
    #>        Taxa prevalence log10foldchange  teststat         pval adjusted_pval
    #> ASV3   ASV3  0.9751553      -0.3618780  9.313926 2.274187e-03  1.855258e-02
    #> ASV8   ASV8  0.9689441       0.3567131  9.881400 1.669578e-03  1.437693e-02
    #> ASV9   ASV9  0.8695652      -0.8925900 19.157084 1.203899e-05  4.665108e-04
    #> ASV14 ASV14  0.7204969       0.9203963 13.159234 2.861058e-04  4.031491e-03
    #> ASV18 ASV18  0.7080745      -1.3929574 28.068324 1.171070e-07  9.075792e-06
    #> ASV20 ASV20  0.4099379       2.2046044 31.758612 1.745735e-08  2.705889e-06
    #>        Kingdom         Phylum               Class           Order
    #> ASV3  Bacteria Proteobacteria Gammaproteobacteria  Pasteurellales
    #> ASV8  Bacteria     Firmicutes             Bacilli Lactobacillales
    #> ASV9  Bacteria Proteobacteria  Betaproteobacteria    Neisseriales
    #> ASV14 Bacteria     Firmicutes             Bacilli Lactobacillales
    #> ASV18 Bacteria   Fusobacteria       Fusobacteriia Fusobacteriales
    #> ASV20 Bacteria  Bacteroidetes         Bacteroidia   Bacteroidales
    #>                 Family         Genus        Species
    #> ASV3   Pasteurellaceae   Haemophilus parainfluenzae
    #> ASV8  Streptococcaceae Streptococcus     salivarius
    #> ASV9     Neisseriaceae     Neisseria       subflava
    #> ASV14 Streptococcaceae Streptococcus           <NA>
    #> ASV18 Fusobacteriaceae Fusobacterium  periodonticum
    #> ASV20   Prevotellaceae    Prevotella           <NA>

We have also developed a `plot` function to generate a volcano plot. The DA taxa are highlighted in red. The user can decide how many points with the smallest p-values are labeled (default 5) with `n.label` argument.

    plot(saliva_output_noadjust, n.label=5)

Volcano plot for differential abundance analysis between saliva samples of children who developed early childhood dental caries and those who didn’t

# Session Information and References

    sessionInfo()
    #> R version 4.6.0 RC (2026-04-17 r89917)
    #> Platform: x86_64-pc-linux-gnu
    #> Running under: Ubuntu 24.04.4 LTS
    #>
    #> Matrix products: default
    #> BLAS:   /home/biocbuild/bbs-3.23-bioc/R/lib/libRblas.so
    #> LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0  LAPACK version 3.12.0
    #>
    #> locale:
    #>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
    #>  [3] LC_TIME=en_GB              LC_COLLATE=C
    #>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
    #>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
    #>  [9] LC_ADDRESS=C               LC_TELEPHONE=C
    #> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
    #>
    #> time zone: America/New_York
    #> tzcode source: system (glibc)
    #>
    #> attached base packages:
    #> [1] stats     graphics  grDevices utils     datasets  methods   base
    #>
    #> other attached packages:
    #> [1] ADAPT_1.6.0
    #>
    #> loaded via a namespace (and not attached):
    #>  [1] SummarizedExperiment_1.42.0 gtable_0.3.6
    #>  [3] xfun_0.57                   bslib_0.10.0
    #>  [5] ggplot2_4.0.3               ggrepel_0.9.8
    #>  [7] Biobase_2.72.0              lattice_0.22-9
    #>  [9] vctrs_0.7.3                 tools_4.6.0
    #> [11] generics_0.1.4              biomformat_1.40.0
    #> [13] stats4_4.6.0                parallel_4.6.0
    #> [15] tibble_3.3.1                cluster_2.1.8.2
    #> [17] pkgconfig_2.0.3             Matrix_1.7-5
    #> [19] data.table_1.18.2.1         RColorBrewer_1.1-3
    #> [21] S7_0.2.2                    S4Vectors_0.50.0
    #> [23] RcppParallel_5.1.11-2       lifecycle_1.0.5
    #> [25] compiler_4.6.0              farver_2.1.2
    #> [27] stringr_1.6.0               Biostrings_2.80.0
    #> [29] Seqinfo_1.2.0               codetools_0.2-20
    #> [31] permute_0.9-10              htmltools_0.5.9
    #> [33] sass_0.4.10                 yaml_2.3.12
    #> [35] pillar_1.11.1               crayon_1.5.3
    #> [37] jquerylib_0.1.4             MASS_7.3-65
    #> [39] cachem_1.1.0                DelayedArray_0.38.0
    #> [41] vegan_2.7-3                 iterators_1.0.14
    #> [43] abind_1.4-8                 foreach_1.5.2
    #> [45] nlme_3.1-169                tidyselect_1.2.1
    #> [47] digest_0.6.39               stringi_1.8.7
    #> [49] dplyr_1.2.1                 reshape2_1.4.5
    #> [51] labeling_0.4.3              splines_4.6.0
    #> [53] RcppArmadillo_15.2.6-1      ade4_1.7-24
    #> [55] fastmap_1.2.0               grid_4.6.0
    #> [57] cli_3.6.6                   SparseArray_1.12.0
    #> [59] magrittr_2.0.5              S4Arrays_1.12.0
    #> [61] survival_3.8-6              dichromat_2.0-0.1
    #> [63] ape_5.8-1                   withr_3.0.2
    #> [65] scales_1.4.0                rmarkdown_2.31
    #> [67] XVector_0.52.0              matrixStats_1.5.0
    #> [69] multtest_2.68.0             igraph_2.3.0
    #> [71] otel_0.2.0                  phyloseq_1.56.0
    #> [73] evaluate_1.0.5              knitr_1.51
    #> [75] GenomicRanges_1.64.0        IRanges_2.46.0
    #> [77] mgcv_1.9-4                  rlang_1.2.0
    #> [79] Rcpp_1.1.1-1.1              glue_1.8.1
    #> [81] BiocGenerics_0.58.0         jsonlite_2.0.0
    #> [83] R6_2.6.1                    plyr_1.8.9
    #> [85] MatrixGenerics_1.24.0

1. Li, H. Microbiome, Metagenomics, and High-Dimensional Compositional Data Analysis. Annual Review of Statistics and Its Application 2, 73–94 (2015).

2. Tobin, J. Estimation of Relationships for Limited Dependent Variables. Econometrica 26, 24 (1958).

3. McMurdie, P. J. & Holmes, S. Phyloseq: An r package for reproducible interactive analysis and graphics of microbiome census data. PLoS ONE 8, e61217 (2013).

4. Blostein, F. et al. Evaluating the ecological hypothesis: early life salivary microbiome assembly predicts dental caries in a longitudinal case-control study. Microbiome 10, 240 (2022).