TP module 20

Analyses stats avec easy16S

Auteur·rice·s
Affiliations

Olivier Rué

Migale

Christelle Hennequet-Antier

MaIAGE

Cédric Midoux

PROSE & MaIAGE

Date de publication

23 juin 2025

Modifié

4 mai 2026

1 Easy16S

Easy16S est une application web conviviale, permettant d’explorer, de visualiser et d’analyser des données de métabarcoding.

Easy16S est développé par Migale en Shiny et s’appuie largement sur le package phyloseq [1].

1.1 Disclaimer

Easy16S facilite l’exploration, la visualisation et l’analyse des données de métabarcoding. Cependant, les utilisateurs doivent veiller à ne pas surinterpréter les résultats. Une interprétation correcte des données métagénomiques nécessite une solide compréhension de l’écologie microbienne, de la biostatistique et du domaine d’étude spécifique. Bien que notre outil soit conçu pour être convivial, la complexité de l’analyse des données métagénomiques implique que les résultats peuvent être trompeurs s’ils ne sont pas évalués avec soin.

Nous avons intégré plusieurs paramètres par défaut et des garde-fous pour guider les utilisateurs et réduire le risque d’utilisation abusive. Toutefois, si vous ne disposez pas de connaissances en métagénomique, il est fortement recommandé de collaborer avec des bioinformaticiens et des biostatisticiens afin de garantir des conclusions solides et fiables issues de vos travaux.

2 Import / Export des données

2.1 Importer les données dans easy16S

Les données peuvent etre importées dans l’application avec le bouton “ Select your data” en haut à gauche de l’interface.

  • “Demo” avec des données d’exemples pour les TP et démonstrations

  • “Input data” pour construire un objet phyloseq à partir de fichiers plats issues de FROGS (ou autres)

    • un fichier BIOM (format standard ou format FROGS )
    • un tableau de métadonnées avec des variables (en colonnes) et des échantillons (en lignes). Assurez-vous que les noms d’échantillons (1ère colonne) sont orthographiés exactement comme dans le fichier BIOM. Le délimiteur et le format des colonnes peuvent être spécifiés
    • un arbre phylogénétique au format Newick
    • un fichier FASTA des séquences représentatives
  • “RData / RDS” pour importer un objet phyloseq déja construit

  • Importez les données obtenues à l’issue du TP-FROGS dans easy16S en utilisant l’option “Input data”

Tips : col_type = cfffffffffflldnnnffffffcfffff

  • Quel est le résultat de l’import ?
library(tidyverse)

## stdBIOM
library(phyloseq)
# physeq <- phyloseq::import_biom(BIOMfilename = "my/file/path/file.biom")

# FROGS BIOM
# remotes::install_github("mahendra-mariadassou/phyloseq-extended", ref = "dev")
library(phyloseq.extended)
physeq <- phyloseq.extended::import_frogs(
    biom = "data/taxonomic_affiliation.biom",
    treefilename = "data/tree.nwk",
    refseqfilename = "data/cluster_filters.fasta",
    refseqFunction = Biostrings::readDNAStringSet
)

sample_data(physeq) <- readr::read_delim(
    "data/MPC_complete_metadata.tsv",
    delim = "\t",
    col_types = "cffffffffffllddddffffffcfffff"
) |>
    column_to_rownames("Sample_ID") |>
    sample_data()

phyloseq::show(physeq)
phyloseq-class experiment-level object
otu_table()   OTU Table:         [ 398 taxa and 72 samples ]
sample_data() Sample Data:       [ 72 samples by 28 sample variables ]
tax_table()   Taxonomy Table:    [ 398 taxa by 7 taxonomic ranks ]
phy_tree()    Phylogenetic Tree: [ 398 tips and 397 internal nodes ]
refseq()      DNAStringSet:      [ 398 reference sequences ]
saveRDS(physeq, "data/physeq.RDS")

2.2 Explorer les données

  • Combien d’echantillons sont présents dans l’objet phyloseq ?

72 échantillons

  • Combien de taxons (=ASVs) sont présents dans l’objet phyloseq ?

398 taxons

  • Quelle est la profondeur de séquençage (nombre de reads) la plus faible ?

La profondeur de séquençage la plus faible est de 6989 reads.

2.3 Transformation et preprocessing des données

Avant de se lancer dans les analyses statistiques, il est important de prétraiter les données, par exemple en selectionnant seulement les échantillons d’intérêt ou en modifiant les données de comptage (rarefaction, normalisation, transformation, etc.). Ceci est possible dans l’onglet “ Preprocess data”. Les transformations s’applique itérativement à partir des données brutes.

  • Selectionnez uniquement les échantillons des AOP AOP2 ou AOP3 et raréfiez le résultat.

  • Combien d’echantillons et de taxons sont présents dans l’objet phyloseq après le prétraitement ?

physeq |>
    subset_samples(AOP %in% c('AOP2', 'AOP3')) |>
    rarefy_even_depth()
phyloseq-class experiment-level object
otu_table()   OTU Table:         [ 343 taxa and 24 samples ]
sample_data() Sample Data:       [ 24 samples by 28 sample variables ]
tax_table()   Taxonomy Table:    [ 343 taxa by 7 taxonomic ranks ]
phy_tree()    Phylogenetic Tree: [ 343 tips and 342 internal nodes ]
refseq()      DNAStringSet:      [ 343 reference sequences ]

Après le prétraitement, il y a 24 échantillons et 347 taxons.

L’historique des transformations appliquées est affiché dans “”.

  • Revenez aux données brutes avec le toggle.

  • Pour de nombreuses analyses, il est important de travailler avec des données raréfiées pour s’affranchir de l’effet de la profondeur de séquençage

physeq_rare <- physeq |>
    rarefy_even_depth(rngseed = 314) # seed for Easy16S reproducibility

2.4 Export des données

Pour faciliter les prochaines analyses, il est possible d’exporter les données courantes (brutes ou prétraitées suivant le toggle) dans différents formats (.biom et .rds) à partir des boutons “”.

  • Exportez les données prétraitées au format .rds puis importez-les à nouveau dans une nouvelle session de easy16S.

3 Tables & Métadonnes

Toutes les tables sont triables, filtrables et exportables au format .csv.

  • Dans l’onglet “ OTU/ASV Table” on retrouve la table d’abondance des ASVs par échantillon.

  • Dans l’onglet “ Taxonomy Table” on retrouve la affiliation taxonomique de chaque ASV.

    • Quelle est l’affiliation taxonomique de l’ASV ID_278 ?

    ID_278 : Sphingobacterium lactis.

  • L’onglet “ Agglomerate ASV Table” permet de visualiser la table d’abondance en aggrégeant les ASVs à un niveau taxonomique donné (ex: Genus).

  • L’onglet “ Sample Data Table” on retrouve les métadonnées associées à chaque échantillon.

physeq |> otu_table() |> head() |> knitr::kable()
AOP1_PPC_S1 AOP1_PPC_S2 AOP1_PPC_S3 AOP1_PPC_S4 AOP1_PPC_S5 AOP1_PPC_S6 AOP1_PPC_W1 AOP1_PPC_W2 AOP1_PPC_W3 AOP1_PPC_W4 AOP1_PPC_W5 AOP1_PPC_W6 AOP2_PPC_S1 AOP2_PPC_S2 AOP2_PPC_S3 AOP2_PPC_S4 AOP2_PPC_S5 AOP2_PPC_S6 AOP2_PPC_W1 AOP2_PPC_W2 AOP2_PPC_W3 AOP2_PPC_W4 AOP2_PPC_W5 AOP2_PPC_W6 AOP3_PPNC_S1 AOP3_PPNC_S2 AOP3_PPNC_S3 AOP3_PPNC_S4 AOP3_PPNC_S5 AOP3_PPNC_S6 AOP3_PPNC_W1 AOP3_PPNC_W2 AOP3_PPNC_W3 AOP3_PPNC_W4 AOP3_PPNC_W5 AOP3_PPNC_W6 AOP4_PPNC_S1 AOP4_PPNC_S2 AOP4_PPNC_S3 AOP4_PPNC_S4 AOP4_PPNC_S5 AOP4_PPNC_S6 AOP4_PPNC_W1 AOP4_PPNC_W2 AOP4_PPNC_W3 AOP4_PPNC_W4 AOP4_PPNC_W5 AOP4_PPNC_W6 AOP5_PPS_S1 AOP5_PPS_S2 AOP5_PPS_S3 AOP5_PPS_S4 AOP5_PPS_S5 AOP5_PPS_S6 AOP5_PPS_W1 AOP5_PPS_W2 AOP5_PPS_W3 AOP5_PPS_W4 AOP5_PPS_W5 AOP5_PPS_W6 AOP6_PPS_S1 AOP6_PPS_S2 AOP6_PPS_S3 AOP6_PPS_S4 AOP6_PPS_S5 AOP6_PPS_S6 AOP6_PPS_W1 AOP6_PPS_W2 AOP6_PPS_W3 AOP6_PPS_W4 AOP6_PPS_W5 AOP6_PPS_W6
ID_329 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 10 13 21 5 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ID_341 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 8 2 2 8 24 0 0 0 2 2 2
ID_78 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 3 1 65 0 9 16 1 3 5 28 6 22 0 0 0 3 3 10 11 5 1 202 173 264 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ID_29 0 1 1 59 15 37 4 12 0 7 1 9 253 257 225 28 49 49 978 917 716 301 415 417 0 0 0 3 0 0 1 0 0 0 0 0 0 0 0 0 1 7 0 0 0 7 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 2
ID_278 1 0 0 1 0 0 0 0 0 0 0 0 16 8 12 3 1 1 26 31 30 19 28 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ID_67 0 0 0 15 7 8 1 0 0 1 0 1 71 85 58 4 8 8 178 161 112 126 195 65 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
physeq |> tax_table() |> head() |> knitr::kable()
Kingdom Phylum Class Order Family Genus Species
ID_329 Bacteria Bacteroidota Bacteroidia Bacteroidales Dysgonomonadaceae Petrimonas Petrimonas_sulfuriphila
ID_341 NA NA NA NA NA NA NA
ID_78 Bacteria Bacteroidota Sphingobacteriia Sphingobacteriales Sphingobacteriaceae Sphingobacterium Sphingobacterium_shayense
ID_29 Bacteria Bacteroidota Sphingobacteriia Sphingobacteriales Sphingobacteriaceae Sphingobacterium Sphingobacterium_lactis
ID_278 Bacteria Bacteroidota Sphingobacteriia Sphingobacteriales Sphingobacteriaceae Sphingobacterium Sphingobacterium_lactis
ID_67 Bacteria Bacteroidota Sphingobacteriia Sphingobacteriales Sphingobacteriaceae Sphingobacterium Sphingobacterium_lactis
metadata <- physeq |>
    sample_data() |>
    as_tibble(rownames = "Sample")

metadata |> head() |> knitr::kable()
Sample Tech_family AOP AOP_code Season Season_code Replicate Localization Dairy_species French_Area Ripening_time Wooden_shelf_use Rind_treatment pH Cheese_aerobic_bacteria_counts Cheese_fungi_counts Cheese_lactic_acid_bacteria_counts study_accession sample_accession experiment_accession run_accession tax_id scientific_name fastq_ftp original_Sample_ID PDO original_AOP Production original_Replicate
AOP1_PPC_S1 PPC AOP1 1 Summer S 1 Rind Cow Bourgogne _Franche-Comte 278 TRUE TRUE 7.33 1.0e+08 80500 1e+05 PRJEB64600 SAMEA114330632 ERX11447984 ERR12064819 1154581 food fermentation metagenome ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/019/ERR12064819/ERR12064819_1.fastq.gz;ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/019/ERR12064819/ERR12064819_2.fastq.gz AOP34_AQ1_a_surf PDO34 AOP34 AQ1 a
AOP1_PPC_S2 PPC AOP1 1 Summer S 2 Rind Cow Bourgogne _Franche-Comte 278 TRUE TRUE 7.57 1.0e+08 80500 1e+05 PRJEB64600 SAMEA114330634 ERX11447985 ERR12064820 1154581 food fermentation metagenome ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/020/ERR12064820/ERR12064820_1.fastq.gz;ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/020/ERR12064820/ERR12064820_2.fastq.gz AOP34_AQ1_b_surf PDO34 AOP34 AQ1 b
AOP1_PPC_S3 PPC AOP1 1 Summer S 3 Rind Cow Bourgogne _Franche-Comte 278 TRUE TRUE 7.59 1.0e+08 80500 1e+05 PRJEB64600 SAMEA114330636 ERX11447986 ERR12064821 1154581 food fermentation metagenome ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/021/ERR12064821/ERR12064821_1.fastq.gz;ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/021/ERR12064821/ERR12064821_2.fastq.gz AOP34_AQ1_c_surf PDO34 AOP34 AQ1 c
AOP1_PPC_S4 PPC AOP1 1 Summer S 4 Rind Cow Bourgogne _Franche-Comte 264 TRUE TRUE 7.47 5.1e+09 206000 0e+00 PRJEB64600 SAMEA114330666 ERX11448001 ERR12064836 1154581 food fermentation metagenome ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/036/ERR12064836/ERR12064836_1.fastq.gz;ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/036/ERR12064836/ERR12064836_2.fastq.gz AOP34_DT1_a_surf PDO34 AOP34 DT1 a
AOP1_PPC_S5 PPC AOP1 1 Summer S 5 Rind Cow Bourgogne _Franche-Comte 264 TRUE TRUE 7.55 5.1e+09 206000 0e+00 PRJEB64600 SAMEA114330668 ERX11448002 ERR12064837 1154581 food fermentation metagenome ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/037/ERR12064837/ERR12064837_1.fastq.gz;ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/037/ERR12064837/ERR12064837_2.fastq.gz AOP34_DT1_b_surf PDO34 AOP34 DT1 b
AOP1_PPC_S6 PPC AOP1 1 Summer S 6 Rind Cow Bourgogne _Franche-Comte 264 TRUE TRUE 7.39 5.1e+09 206000 0e+00 PRJEB64600 SAMEA114330670 ERX11448003 ERR12064838 1154581 food fermentation metagenome ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/038/ERR12064838/ERR12064838_1.fastq.gz;ftp.sra.ebi.ac.uk/vol1/fastq/ERR120/038/ERR12064838/ERR12064838_2.fastq.gz AOP34_DT1_c_surf PDO34 AOP34 DT1 c

Metadata” permet de visualiser les métadonnées à l’aide du package {esquisse}. Ceci est utile pour explorer et évaluer les associations entre les variables d’échantillons (mais pas les données de métabarcoding).

4 Barplots

La visualisation la plus commune est le barplot d’abondance relative des taxons. Dans easy16S, il est possible de visualiser les abondances relatives de chaque échantillon à différents niveaux taxonomiques avec l’onglet “ Barplot”. Il est possible de se concentrer sur un taxon d’intérêt (Selected filter taxa), de choisir le niveau taxonomique de representation (Taxonomic rank used for coloring), de regrouper les échantillons par une variable d’intérêt (Subplot) et de jouer sur l’ordre et le labelling des échantillons (Sample ordrer* et Sample label).

  • Visualiser l’ensemble des données au niveau Phylum en regroupant les échantillons en fonction de AOP et en les ordonnant en fonction de pH.
plot_composition(
    physeq = physeq,
    taxaRank1 = NULL,
    taxaRank2 = "Phylum",
    sampleOrder = metadata |> arrange(pH) |> pull(Sample),
    facet_grid = "~AOP",
    scales = "free",
    space = "free"
)
         taxa Kingdom  Phylum rank
ID_159 ID_159 Unknown Unknown    5

  • Visualiser l’abondance relative des Genus de la famille des Sphingobacterium.
plot_composition(
    physeq = physeq,
    taxaRank1 = "Genus",
    taxaSet1 = "Sphingobacterium",
    taxaRank2 = "Species",
    facet_grid = "~AOP",
    scales = "free",
    space = "free"
)

  • Exportez le plot en .png (voir en haut a droite) en cliquant sur .

5 Rarefaction

L’onglet “ Rarefaction” permet de tracer les courbes de rarefaction pour chaque echantillon.

  • Comparez les courbes sur les données brutes et données transformées après raréfaction en activant “Show min sample threshold”.
physeq |>
    ggrare(step = 100, se = FALSE, color = "AOP", plot = FALSE) +
    geom_vline(xintercept = min(sample_sums(physeq)), color = "gray60")
rarefying sample AOP1_PPC_S1
rarefying sample AOP1_PPC_S2
rarefying sample AOP1_PPC_S3
rarefying sample AOP1_PPC_S4
rarefying sample AOP1_PPC_S5
rarefying sample AOP1_PPC_S6
rarefying sample AOP1_PPC_W1
rarefying sample AOP1_PPC_W2
rarefying sample AOP1_PPC_W3
rarefying sample AOP1_PPC_W4
rarefying sample AOP1_PPC_W5
rarefying sample AOP1_PPC_W6
rarefying sample AOP2_PPC_S1
rarefying sample AOP2_PPC_S2
rarefying sample AOP2_PPC_S3
rarefying sample AOP2_PPC_S4
rarefying sample AOP2_PPC_S5
rarefying sample AOP2_PPC_S6
rarefying sample AOP2_PPC_W1
rarefying sample AOP2_PPC_W2
rarefying sample AOP2_PPC_W3
rarefying sample AOP2_PPC_W4
rarefying sample AOP2_PPC_W5
rarefying sample AOP2_PPC_W6
rarefying sample AOP3_PPNC_S1
rarefying sample AOP3_PPNC_S2
rarefying sample AOP3_PPNC_S3
rarefying sample AOP3_PPNC_S4
rarefying sample AOP3_PPNC_S5
rarefying sample AOP3_PPNC_S6
rarefying sample AOP3_PPNC_W1
rarefying sample AOP3_PPNC_W2
rarefying sample AOP3_PPNC_W3
rarefying sample AOP3_PPNC_W4
rarefying sample AOP3_PPNC_W5
rarefying sample AOP3_PPNC_W6
rarefying sample AOP4_PPNC_S1
rarefying sample AOP4_PPNC_S2
rarefying sample AOP4_PPNC_S3
rarefying sample AOP4_PPNC_S4
rarefying sample AOP4_PPNC_S5
rarefying sample AOP4_PPNC_S6
rarefying sample AOP4_PPNC_W1
rarefying sample AOP4_PPNC_W2
rarefying sample AOP4_PPNC_W3
rarefying sample AOP4_PPNC_W4
rarefying sample AOP4_PPNC_W5
rarefying sample AOP4_PPNC_W6
rarefying sample AOP5_PPS_S1
rarefying sample AOP5_PPS_S2
rarefying sample AOP5_PPS_S3
rarefying sample AOP5_PPS_S4
rarefying sample AOP5_PPS_S5
rarefying sample AOP5_PPS_S6
rarefying sample AOP5_PPS_W1
rarefying sample AOP5_PPS_W2
rarefying sample AOP5_PPS_W3
rarefying sample AOP5_PPS_W4
rarefying sample AOP5_PPS_W5
rarefying sample AOP5_PPS_W6
rarefying sample AOP6_PPS_S1
rarefying sample AOP6_PPS_S2
rarefying sample AOP6_PPS_S3
rarefying sample AOP6_PPS_S4
rarefying sample AOP6_PPS_S5
rarefying sample AOP6_PPS_S6
rarefying sample AOP6_PPS_W1
rarefying sample AOP6_PPS_W2
rarefying sample AOP6_PPS_W3
rarefying sample AOP6_PPS_W4
rarefying sample AOP6_PPS_W5
rarefying sample AOP6_PPS_W6

6 Heatmap

On peut afficher une carte de chaleur de l’abondance de chaque taxa pour chaque sample avec l’onglet “ Heatmap” dédié. Ceci permet d’observer les patterns structurant les communautés d’échatillons.

Les ASVs peuvent etre regroupés à chaque rang taxonomique. Les samples peuvent etre regroupés, ordonnés et labelés en fonction des variables d’interet.

Il s’aggit des données de comptage. Il faut s’assurer que les données sont normalisées ou raréfiées.

  • Visualisez la structuration des communautés en agglomérant au niveau Order pour comparer les différents AOP.
physeq_rare |>
    fast_tax_glom(
        taxrank = "Order"
    ) |>
    plot_heatmap(
        method = "NMDS",
        distance = "bray",
        taxa.label = "Order",
        low = "yellow",
        high = "red",
        na.value = "white"
    ) +
    facet_grid(
        cols = vars(AOP),
        scales = "free_x",
        space = "free"
    )

7 α-diversity

La diversité α mesure la richesse au sein de chaque échantillon individuelement. Différentes métriques sont disponibles (cf. slides).

7.1 α - Table & Plot

On peut visualiser les métriques de chaque échantillon sous forme de table et de plot (avec boxplot par catégorie par exemple)

  • Quels sont les AOP et Season avec un indice Chao1 faibles et forts ? Idem avec InvSimpson ?
physeq_rare |>
    plot_richness(
        x = "AOP",
        color = "Season",
        measures = c("Observed", "Chao1", "Shannon", "InvSimpson")
    ) +
    geom_boxplot() +
    scale_color_brewer(palette = "Paired")

7.2 α - ANOVA

Cette section effectue une analyse de variance (ANOVA) sur une métrique de diversité, en fonction d’une ou plusieurs métadonnées afin d’évaluer l’impact d’une covariable d’intérêt sur la diversité alpha.

  • Existe-il une corélation significative entre la variable AOP et la richesse Chao1 ?
anova_data <- inner_join(
    as_tibble(
        estimate_richness(physeq_rare, measures = "Chao1"),
        rownames = "Sample"
    ),
    metadata,
    by = join_by(Sample)
)

lm(formula = Chao1 ~ AOP, data = anova_data) |> anova()
Analysis of Variance Table

Response: Chao1
          Df Sum Sq Mean Sq F value    Pr(>F)    
AOP        5  55526 11105.3  26.771 1.116e-14 ***
Residuals 66  27378   414.8                      
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

8 β-diversity

La diversité β mesure la dissimilarité entre les échantillons. On mesure donc la “distance” entre chaque paires d’échantillon. Ici aussi, il existe diverses métriques de distances, s’appuyant sur qualitatif/quantitatif et utilisant la distance phylogénétique ou non. Le choix de la mesure est essantiel et aura une forte incidence sur les sorties et leurs interprétations.

Après avoir la distance utilisée, on peut exploiter les résultats sous diverses forme :

  • Table des paires de distance
  • Heatmap de la matrice des distances
  • Dendogramme de clustering
  • MultiDimensional Scaling
  • Multivariate ANOVA

8.1 β - Table

  • Pour chaque mesure, quels sont les deux échantillons les plus éloignés ?
dist_Bray <- physeq_rare |>
    distance(method = "bray")

dist_Bray |>
    broom::tidy()
# A tibble: 2,556 × 3
   item1       item2       distance
   <fct>       <fct>          <dbl>
 1 AOP1_PPC_S1 AOP1_PPC_S2   0.0750
 2 AOP1_PPC_S1 AOP1_PPC_S3   0.153 
 3 AOP1_PPC_S1 AOP1_PPC_S4   0.386 
 4 AOP1_PPC_S1 AOP1_PPC_S5   0.431 
 5 AOP1_PPC_S1 AOP1_PPC_S6   0.422 
 6 AOP1_PPC_S1 AOP1_PPC_W1   0.315 
 7 AOP1_PPC_S1 AOP1_PPC_W2   0.378 
 8 AOP1_PPC_S1 AOP1_PPC_W3   0.239 
 9 AOP1_PPC_S1 AOP1_PPC_W4   0.388 
10 AOP1_PPC_S1 AOP1_PPC_W5   0.412 
# ℹ 2,546 more rows
dist_Bray |>
    broom::tidy() |>
    filter(distance %in% c(min(distance), max(distance)))
# A tibble: 2 × 3
  item1       item2       distance
  <fct>       <fct>          <dbl>
1 AOP5_PPS_W1 AOP6_PPS_S2   0.983 
2 AOP6_PPS_S4 AOP6_PPS_S6   0.0554
dist_CC <- physeq_rare |>
    distance(method = "cc")

dist_CC |>
    broom::tidy()
# A tibble: 2,556 × 3
   item1       item2       distance
   <fct>       <fct>          <dbl>
 1 AOP1_PPC_S1 AOP1_PPC_S2    0.288
 2 AOP1_PPC_S1 AOP1_PPC_S3    0.328
 3 AOP1_PPC_S1 AOP1_PPC_S4    0.453
 4 AOP1_PPC_S1 AOP1_PPC_S5    0.445
 5 AOP1_PPC_S1 AOP1_PPC_S6    0.461
 6 AOP1_PPC_S1 AOP1_PPC_W1    0.432
 7 AOP1_PPC_S1 AOP1_PPC_W2    0.356
 8 AOP1_PPC_S1 AOP1_PPC_W3    0.346
 9 AOP1_PPC_S1 AOP1_PPC_W4    0.399
10 AOP1_PPC_S1 AOP1_PPC_W5    0.379
# ℹ 2,546 more rows
dist_CC |>
    broom::tidy() |>
    filter(distance %in% c(min(distance), max(distance)))
# A tibble: 3 × 3
  item1       item2       distance
  <fct>       <fct>          <dbl>
1 AOP2_PPC_S3 AOP5_PPS_S3    0.930
2 AOP2_PPC_S5 AOP2_PPC_S6    0.243
3 AOP2_PPC_S5 AOP5_PPS_S4    0.930
  • Bray-Curtis AOP5_PPS_W1 - AOP6_PPS_S2 : 0.983
  • Jaccard (cc) AOP2_PPC_S3 - AOP5_PPS_S3 : 0.930

8.2 β - Samples heatmap

On retrouve ici la matrice des distances sous forme de carte de chaleur.

  • Visualisez les blocs d’échantillons proches
dist_Bray |>
    plot_dist_as_heatmap(show.names = TRUE) +
    scale_fill_gradient(
        low = "firebrick",
        high = "antiquewhite",
        limits = c(0, 1)
    )

8.3 β - Samples clustering

Toujours avec la même matrice de distance entre échantillon, on peut reconstruire un dendogramme de clustering. La methode de partitionnement la plus courament utilisée est ward.D2 mais d’autres méthodes sont disponibles.

Grace à ce plot on peut visualiser le regrouppement des échantillons.

  • Tracer le dendogramme de clustering à partir des distance de Bray-Curtis et Jaccard en coloriant les samples en fonction de AOP ?
physeq_rare |>
    plot_clust(
        dist = dist_Bray,
        method = "ward.D2",
        color = "AOP"
    )

8.4 β - MultiDimensional Scaling

De la même manière, il est possible de projeter le nuage de points des communautés sur un plan, en cherchant à préserver les distances etre les échantillons.

  • Visualisiez la matrice de distance de Jaccard (cc) avec une méthode d’ordination MDS en colorant les échantillons en fonction de AOP
physeq_rare |>
    plot_ordination(
        ordinate(physeq_rare, "MDS", dist_CC),
        color = "AOP"
    ) +
    stat_ellipse(aes(group = AOP))

8.5 β - Multivariate ANOVA

Enfin, il est possible d’effectuer une analyse de variance de cette matrice de distance avec un test de permutation. On évalue ainsi l’impact d’une ou plusieurs covariable sur la structure de la communauté. Le test vegan::adonis2() compare la structure de nos données à 9999 structures générées par permutations aléatoires. La Permutational Multivariate ANOVA prend en charge les plans d’expérience complexes, mais elle ne teste que les effets localisé (telque, est-ce que les communautés typiques sont similaires dans les groupes A et B ?) et suppose des dispersions égales (c’est-à-dire une variabilité biologique identique dans les deux groupes).

  • Observe-t-on un effet significatif de AOP sur la matrice de distance de Jaccard (cc) ?
vegan::adonis2(
    formula = dist_CC ~ AOP,
    data = metadata,
    by = "terms",
    perm = 9999
) #|> broom::tidy()
Permutation test for adonis under reduced model
Terms added sequentially (first to last)
Permutation: free
Number of permutations: 9999

vegan::adonis2(formula = dist_CC ~ AOP, data = metadata, permutations = 9999, by = "terms")
         Df SumOfSqs      R2      F Pr(>F)    
AOP       5  11.0288 0.54946 16.098  1e-04 ***
Residual 66   9.0433 0.45054                  
Total    71  20.0721 1.00000                  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

9 PCA

Bien que l’usage de MDS soit le plus souvent recommandée pour l’analyse du microbiome, l’analyse en composantes principales (ACP), après une transformation appropriée des données, peut constituer une alternative. Les abondances transformées peuvent être centrées et/ou mises à l’échelle au cours de l’analyse. La matrice d’abondance transformée est ansi utilisé pour une ACP.

  • Préférant les MDS, nous ne passeront pas plus de temps sur les ACP

10 Differential abundance

Une fois que l’on a observé un effet significatif d’une covariable sur la strucutation de nos communautés, on cherche souvant a identifier quels ASVs sont surreprésentés ou sous-représentés en fonction d’une variable expérimentale donnée (catégorielle ou numérique). Le package {DESeq2}, historiquement développé pour les analyses RNA-Seq est courament utilisé pour cela.

  • Quels ASVs sont sur-abondants ou sous-abondants en fonction de AOP : AOP3 versus AOP5 ?
physeq_dds <- physeq_rare |>
    phyloseq_to_deseq2(design = ~AOP) |>
    DESeq2::DESeq(sfType = "poscounts")

DESeq2::results(
    physeq_dds,
    contrast = c("AOP", "AOP3", "AOP5"),
    tidy = TRUE
) |>
    rename(ASV = row) |>
    mutate(
        evidence = -log10(padj),
        evolution = case_when(
            padj <= 0.05 & log2FoldChange < 0 ~ "Down",
            padj <= 0.05 & log2FoldChange > 0 ~ "Up",
            TRUE ~ "Not DA"
        )
    ) |>
    filter(evolution %in% c('Up', "Down")) |>
    knitr::kable()
ASV baseMean log2FoldChange lfcSE stat pvalue padj evidence evolution
ID_78 7.1790639 5.958483 1.6416826 3.629498 0.0002840 0.0016436 2.784203 Up
ID_77 8.6607765 8.045355 0.9978496 8.062694 0.0000000 0.0000000 13.691144 Up
ID_89 6.0787287 7.779825 1.3058902 5.957488 0.0000000 0.0000000 7.424424 Up
ID_61 13.7837426 6.099246 1.2767992 4.776981 0.0000018 0.0000139 4.857843 Up
ID_32 31.9240059 8.680199 0.8776978 9.889735 0.0000000 0.0000000 20.754004 Up
ID_55 17.7297586 8.550629 1.2248516 6.980951 0.0000000 0.0000000 10.251819 Up
ID_18 40.8486327 30.111687 2.8833733 10.443215 0.0000000 0.0000000 23.175206 Up
ID_65 12.4520717 3.184388 0.8584847 3.709312 0.0002078 0.0012214 2.913156 Up
ID_155 2.5927310 5.261168 1.7409224 3.022058 0.0025106 0.0118402 1.926640 Up
ID_23 43.7635706 -3.265027 0.4743217 -6.883571 0.0000000 0.0000000 9.973964 Down
ID_210 4.5387846 4.932116 0.7501015 6.575265 0.0000000 0.0000000 9.093328 Up
ID_319 2.4681448 3.498000 0.8767437 3.989763 0.0000661 0.0004075 3.389869 Up
ID_232 2.7516326 4.605973 0.8708633 5.288974 0.0000001 0.0000012 5.919080 Up
ID_22 84.3351109 2.575499 0.5066958 5.082930 0.0000004 0.0000032 5.491248 Up
ID_24 59.8570553 2.438259 0.4601826 5.298459 0.0000001 0.0000012 5.930336 Up
ID_103 10.2407872 6.330269 1.0199558 6.206415 0.0000000 0.0000000 8.064092 Up
ID_9 432.6585008 2.292035 0.4171579 5.494407 0.0000000 0.0000004 6.356101 Up
ID_41 31.2077318 3.904544 0.8298761 4.704972 0.0000025 0.0000194 4.712243 Up
ID_15 77.0897486 2.953419 0.7670584 3.850319 0.0001180 0.0007153 3.145527 Up
ID_45 43.2952370 4.628562 0.7861677 5.887500 0.0000000 0.0000001 7.255924 Up
ID_441 1.2335661 3.804505 1.2126254 3.137412 0.0017045 0.0086814 2.061409 Up
ID_557 1.6114705 2.702878 1.0081350 2.681068 0.0073388 0.0318569 1.496796 Up
ID_25 46.1985620 -10.283327 1.7673460 -5.818514 0.0000000 0.0000001 7.106745 Down
ID_132 2.5996650 4.789666 1.5606649 3.068991 0.0021478 0.0103857 1.983563 Up
ID_1 1216.2173417 10.214587 0.6115109 16.703852 0.0000000 0.0000000 59.629518 Up
ID_31 53.1466579 8.504307 0.7906963 10.755466 0.0000000 0.0000000 24.573994 Up
ID_442 0.9460377 3.786498 1.3627133 2.778646 0.0054586 0.0248236 1.605135 Up
ID_882 1.1014617 4.346521 1.0425613 4.169079 0.0000306 0.0002014 3.695881 Up
ID_300 1.3151702 3.793890 1.2183001 3.114085 0.0018452 0.0091539 2.038393 Up
ID_186 2.8329009 5.224520 0.9973389 5.238460 0.0000002 0.0000015 5.821415 Up
ID_194 1.9464739 4.751274 1.0574280 4.493236 0.0000070 0.0000506 4.296192 Up
ID_242 1.9798681 4.530182 1.2759719 3.550378 0.0003847 0.0021610 2.665348 Up
ID_251 1.7383135 3.668296 0.9012034 4.070442 0.0000469 0.0002939 3.531871 Up
ID_264 1.7743653 2.842404 1.0634480 2.672819 0.0075217 0.0322841 1.491012 Up
ID_16 63.4944941 4.143414 0.7621997 5.436127 0.0000001 0.0000006 6.238233 Up
ID_10 181.1876355 2.539287 0.5951322 4.266762 0.0000198 0.0001354 3.868347 Up
ID_85 10.7912500 7.692765 1.0097716 7.618321 0.0000000 0.0000000 12.263283 Up
ID_128 5.4527667 4.331894 1.2356208 3.505844 0.0004552 0.0024839 2.604869 Up
ID_106 4.4073194 6.168258 1.4457208 4.266563 0.0000199 0.0001354 3.868347 Up
ID_181 1.5333030 4.911575 1.7605445 2.789805 0.0052740 0.0242730 1.614876 Up
ID_200 3.1801743 5.473226 0.9155489 5.978082 0.0000000 0.0000000 7.462191 Up
ID_151 3.0113689 5.588543 1.0073258 5.547900 0.0000000 0.0000004 6.448220 Up
ID_157 1.3771993 -4.711049 1.8128088 -2.598757 0.0093562 0.0392755 1.405878 Down
ID_213 1.7137905 -2.835752 1.1185104 -2.535293 0.0112353 0.0456584 1.340479 Down
ID_34 25.0927451 4.164642 0.8615300 4.834006 0.0000013 0.0000106 4.972682 Up
ID_13 69.5482850 -25.545097 1.3885541 -18.396905 0.0000000 0.0000000 72.274653 Down
ID_42 18.9926401 -5.563853 1.1332217 -4.909766 0.0000009 0.0000074 5.130110 Down
ID_71 8.6981013 -22.997003 1.8600735 -12.363492 0.0000000 0.0000000 32.581327 Down
ID_6 182.6358388 -9.336822 0.7680498 -12.156532 0.0000000 0.0000000 31.539090 Down
ID_576 0.9467260 -3.807398 1.2396143 -3.071438 0.0021303 0.0103857 1.983563 Down
ID_20 61.8988125 8.050637 1.9764897 4.073200 0.0000464 0.0002939 3.531871 Up
ID_36 30.3435248 8.050892 0.9442836 8.525926 0.0000000 0.0000000 15.316441 Up
ID_33 5.7291142 -33.764221 4.2129322 -8.014423 0.0000000 0.0000000 13.550056 Down
ID_58 12.2336089 3.614020 1.1203494 3.225797 0.0012562 0.0064848 2.188101 Up
ID_227 1.3462465 3.852054 1.0051382 3.832362 0.0001269 0.0007575 3.120591 Up
ID_50 14.3423324 7.440574 0.9681142 7.685636 0.0000000 0.0000000 12.465862 Up
ID_52 26.1281644 8.247592 1.0419244 7.915730 0.0000000 0.0000000 13.231464 Up
ID_3 362.7305286 -2.000215 0.7652999 -2.613635 0.0089585 0.0380237 1.419946 Down
ID_83 5.5277764 -7.248140 2.0563927 -3.524687 0.0004240 0.0023473 2.629436 Down
ID_203 1.6219842 4.453955 1.7199641 2.589563 0.0096098 0.0399015 1.399011 Up
ID_76 13.2272078 3.191589 0.6448525 4.949332 0.0000007 0.0000062 5.208720 Up
ID_193 2.0701880 5.146593 0.9431774 5.456655 0.0000000 0.0000005 6.276094 Up
ID_105 7.9892746 5.563215 0.7799666 7.132632 0.0000000 0.0000000 10.703399 Up
ID_2 905.3050417 1.564957 0.5578802 2.805186 0.0050288 0.0234267 1.630289 Up
ID_209 1.8337567 4.729431 1.1424718 4.139648 0.0000348 0.0002252 3.647410 Up
ID_257 1.4749077 4.233113 0.9458515 4.475452 0.0000076 0.0000539 4.268091 Up
ID_219 3.1161392 4.283865 0.7320267 5.852061 0.0000000 0.0000001 7.178890 Up
ID_64 11.6353859 8.672818 1.0512725 8.249828 0.0000000 0.0000000 14.331517 Up
ID_208 2.4738522 4.388585 0.8355951 5.252047 0.0000002 0.0000014 5.842697 Up
ID_14 43.5192580 -4.818970 0.8945925 -5.386777 0.0000001 0.0000007 6.130423 Down
ID_104 4.8074696 7.493959 2.7760330 2.699521 0.0069439 0.0304895 1.515850 Up
ID_114 3.8666412 6.552095 0.9893138 6.622868 0.0000000 0.0000000 9.213452 Up
ID_38 25.8412739 32.330362 2.0221942 15.987763 0.0000000 0.0000000 54.828224 Up
ID_27 40.2356042 10.631783 1.9310097 5.505816 0.0000000 0.0000004 6.371237 Up
ID_26 65.6256940 32.647536 3.4012164 9.598782 0.0000000 0.0000000 19.551411 Up
ID_123 3.5476758 6.523811 1.4395808 4.531743 0.0000058 0.0000430 4.366792 Up
ID_59 16.1437930 8.816409 1.7241881 5.113368 0.0000003 0.0000028 5.551081 Up
ID_119 3.3475415 6.736912 2.1501658 3.133206 0.0017291 0.0086909 2.060935 Up
ID_180 2.6910275 5.880237 2.3139054 2.541261 0.0110454 0.0453691 1.343240 Up
ID_161 2.0187416 5.877159 1.6269560 3.612365 0.0003034 0.0017299 2.761972 Up
ID_109 6.0840495 5.748670 1.7109446 3.359939 0.0007796 0.0040795 2.389390 Up
ID_60 13.1243624 7.395697 1.7567647 4.209839 0.0000256 0.0001713 3.766331 Up
ID_56 12.4933525 5.055045 1.4977499 3.375093 0.0007379 0.0039150 2.407267 Up
ID_48 21.0160141 31.887053 1.9797122 16.106913 0.0000000 0.0000000 55.536872 Up
ID_53 14.7439688 8.163479 1.7486701 4.668393 0.0000030 0.0000227 4.643255 Up
ID_82 7.7223036 7.297233 1.4534139 5.020753 0.0000005 0.0000044 5.359602 Up
ID_139 2.6012075 4.247590 1.5689458 2.707289 0.0067835 0.0301314 1.520980 Up
ID_108 11.1314609 8.740283 2.8805504 3.034241 0.0024114 0.0115145 1.938754 Up
ID_88 6.2203827 6.727188 1.9916344 3.377722 0.0007309 0.0039150 2.407267 Up
ID_72 9.1036192 -7.983280 2.9023571 -2.750619 0.0059483 0.0267322 1.572965 Down
ID_11 221.0165486 5.363817 0.9613161 5.579660 0.0000000 0.0000003 6.513060 Up
ID_90 8.1898937 5.522407 1.0678750 5.171398 0.0000002 0.0000021 5.675046 Up
ID_19 97.5137659 -11.406860 2.0715635 -5.506401 0.0000000 0.0000004 6.371237 Down
ID_96 4.9642442 30.868687 2.1625062 14.274497 0.0000000 0.0000000 43.617827 Up

11 Homeworks

11.1 food - [2]

Ce jeu de données s’interesse aux communautés bactériennes présentes dans 8 matrices alimentaires différentes (EnvType), répartis en 4 produits carnés et 4 produits de la mer.

  • Quel est le microbiote caractéristique de chaque matrice ?
  • Comment s’organise les différentes matrices ?

11.2 GlobalPatterns - [3]

Cette étude analyse des communautés bactériennes issues d’environnements très divers (SampleType) pour étudier les structures écologiques mondiales.

  • Comment est distribuée la profondeur de séquençage ? Qu’est-il nécéssaire de mettre en place ?
  • Comparez les diversités α entre les environnements (SampleType). Quels environnements sont les plus ou moins diversifiés ? Cela correspond-il à votre intuition ?
  • À partir des diversités β, que pouvez-vous dire sur les différents environnements ?

Les références

1. McMurdie PJ, Holmes S. phyloseq: an R package for reproducible interactive analysis and graphics of microbiome census data. PloS one. 2013;8:e61217.
2. Chaillou S, Chaulot-Talmon A, Caekebeke H, Cardinal M, Christieans S, Denis C, et al. Origin and ecological selection of core and food-specific bacterial communities associated with meat and seafood spoilage. The ISME Journal. 2014;9:1105‑18. doi:10.1038/ismej.2014.202.
3. Caporaso JG, Lauber CL, Walters WA, Berg-Lyons D, Lozupone CA, Turnbaugh PJ, et al. Global patterns of 16S rRNA diversity at a depth of millions of sequences per sample. Proceedings of the National Academy of Sciences. 2010;108:4516‑22. doi:10.1073/pnas.1000080107.

Réutilisation


A work by Migale Bioinformatics Facility
Université Paris-Saclay, INRAE, MaIAGE, 78350, Jouy-en-Josas, France
Université Paris-Saclay, INRAE, BioinfOmics, MIGALE bioinformatics facility, 78350, Jouy-en-Josas, France