20  Introductory (Dutch)

20.1 Introductie

Hallo en welkom bij een complete workflow met de nieuwste R/Bioconductor-tools voor microbiome data science. In deze tutorial leiden we je door enkele basisstappen van een compositieanalyse-studie met behulp van OMA. Deze stappen zijn toepasbaar op vrijwel al je projecten en zullen je helpen de fundamentele concepten te begrijpen die je toekomstige microbiome-analyses naar een hoger niveau zullen tillen 🚀.

20.2 Data importeren

Bij het gebruik van microbiome-pakketten zijn er veel verschillende manieren om je data te importeren. Laten we eerst alle paketten laden:

# List of packages that we need
packages <- c(
    "ggplot2", "knitr", "mia", "dplyr", "miaViz", "vegan", "DT",
    "scater", "patchwork", "sechm", "plotly"
    )

# Get packages that are already installed installed
packages_already_installed <- packages[ packages %in% installed.packages() ]

# Get packages that need to be installed
packages_need_to_install <- setdiff( packages, packages_already_installed )

# Loads BiocManager into the session. Install it if it not already installed.
if( !require("BiocManager") ){
    install.packages("BiocManager")
    library("BiocManager")
}

# If there are packages that need to be installed, installs them with BiocManager
# Updates old packages.
if( length(packages_need_to_install) > 0 ) {
   install(packages_need_to_install, ask = FALSE)
}

# Load all packages into session. Stop if there are packages that were not
# successfully loaded
pkgs_not_loaded <- !sapply(packages, require, character.only = TRUE)
pkgs_not_loaded <- names(pkgs_not_loaded)[ pkgs_not_loaded ]
if( length(pkgs_not_loaded) > 0 ){
    stop("Error in loading the following packages into the session: '", paste0(pkgs_not_loaded, collapse = "', '"), "'")
}

Je kunt er zowel voor kiezen om je eigen data te gebruiken als een van de ingebouwde datasets die door mia worden aangeboden, welke je kunt vinden in het OMA boek@sec-example-data :

In deze tutorial gebruiken we de C Tengeler et al. (2020) dataset. Deze dataset is gemaakt door A.C. Tengeler om de impact van aangetaste microbiomen op de hersenstructuur aan te tonen. Hier is hoe we de data in onze R-omgeving kunnen laden:

C Tengeler, Anouk, Sarita A Dam, Maximilian Wiesmann, Jilly Naaijen, Miranda van Bodegom, Clara Belzer, Pieter J Dederen, et al. 2020. “Gut Microbiota from Persons with Attention-Deficit/Hyperactivity Disorder Affects the Brain in Mice.” Microbiome 8: 1–14. https://doi.org/10.1186/s40168-020-00816-x.
data("Tengeler2020", pakket="mia")
tse <- Tengeler2020

Er zijn verschillende andere manieren om je data te importeren via het mia pakket. Deze omvatten het gebruik van zowel je eigen data(Section 2.4.2) of door een bestaand object om te zetten naar een TreeSummarizedExperiment object zoals vermeld in dit gedeelte van het OMA boek: Section 2.4.6


20.3 Microbiële data opslaan

TreeSummarizedExperiment of TSE objecten zijn het type object dat wordt gebruikt binnen mia om data op te slaan. Een TreeSummarizedExperiment is een veelzijdig en multifunctioneel datatype dat een efficiënte manier biedt om data op te slaan en te benaderen.

20.3.1 Assays

Een assay(Section 2.2.1) is een methode om de aanwezigheid en hoeveelheid van verschillende soorten microben in een monster te detecteren en te meten. Als je bijvoorbeeld wilt weten hoeveel bacteriën van een bepaald type in je darmen aanwezig zijn, kun je een assay gebruiken om dit te bepalen. In het volgende voorbeeld selecteren we een subset van een assay door alleen de eerste 5 rijen en de eerste 10 kolommen te tonen. Dit maakt het eenvoudiger om te begrijpen en te lezen. Later in de worklow zal er meer uitleg worden gegeven over het maken van subsets.

assay(tse)[1:5,1:10] 
##                   A110   A12  A15  A19  A21  A23  A25  A28 A29  A34
##  Bacteroides     17722 11630    0 8806 1740 1791 2368 1316 252 5702
##  Bacteroides_1   12052     0 2679 2776  540  229    0    0   0 6347
##  Parabacteroides     0   970    0  549  145    0  109  119  31    0
##  Bacteroides_2       0  1911    0 5497  659    0  588  542 141    0
##  Akkermansia      1143  1891 1212  584   84  700  440  244  25 1611

20.3.2 colData

Een ander belangrijk aspect van microbiome-analyse is monsterdata(Section 3.2).

# verandert de colData in een dataframe
tse_df_colData <- as.data.frame(colData(tse))

# laat een interactieve tabel zien
datatable(tse_df_colData,options = list(pageLength = 5),rownames = FALSE)

n het bovenstaande voorbeeld retourneert colData(tse) een DataFrame met 26 rijen en 10 kolommen. Elke rij correspondeert met een specifiek monster en elke kolom bevat gegevens over dat monster.

20.3.3 rowData

rowData(Section 2.2.3) bevat gegevens van een type microbe, voornamelijk taxonomische informatie.

tse_df_rowData <- as.data.frame(rowData(tse))
datatable(tse_df_rowData, options = list(pageLength = 5))

Hierboven retourneert rowData(tse) een DataFrame met 151 rijen en 7 colommen. Iedere rij verwijst naar een organisme terwijl iedere kolom naar een taxonomische rang verwijst.

In dit voorbeeld geeft de kolom genaamd Kingdom aan of het organisme behoort tot het rijk van bacteriën of archaea. Phylum geeft aan tot welke stam een micro-organisme behoort, en zo verder tot het niveau van de soort micro-organisme.

Om de structuur van een TreeSummarizedExperiment te verduidelijken is hier een artikel van Huang et al. (2021) dat gebruik maakt van dit soort type object. Bekijk ook figuur 1 hieronder.

Huang, Ruizhu, Charlotte Soneson, Felix G. M. Ernst, et al. 2021. “TreeSummarizedExperiment: A S4 Class for Data with Hierarchical Structure [Version 2; Peer Review: 3 Approved].” F1000Research 9: 1246. https://doi.org/10.12688/f1000research.26669.2.

1. microbiële data opslaan : de structuur van een TreeSummarizedExperiment

1. microbiële data opslaan : de structuur van een TreeSummarizedExperiment

20.4 Data verwerking

In sommige gevallen is het nodig om je data te transformeren om een bepaald soort resultaat te behalen. In de volgende rubriek zullen we bespreken hoe je gegevens kunt samenvoegen, je gegevens kunt subsetten en meer. Een TreeSummarizedExperiment maakt het mogelijk om gegevens op een handige manier te manipuleren met dplyr.

20.4.1 Subsetten

In sommige gevallen hoeft u slechts een deel van uw originele TreeSummarizedExperiment te behouden.

Met de Tengeler2020 dataset, kunnen we de focus leggen op een bepaald cohort bijvoorbeeld. Dit resultaat kan op de volgende manier behaald worden:

tse_subset_by_sample <- tse[ , tse$cohort =="Cohort_1"]

Dit creëert een TreeSummarizedExperiment-object dat alleen bestaat uit monsters van het eerste cohort. Om het resulterende object beter te visualiseren, kunnen we de meltAssay-methode gebruiken en specificeren welk type kolom behouden moet blijven:

molten_tse <- meltAssay(tse_subset_by_sample,
                        add_row_data = TRUE,
                        add_col_data = TRUE,
                        assay.type = "counts")

datatable(molten_tse,options = list(pageLength = 5),rownames = FALSE)

20.4.2 Data samenvoegen

Om de analyse verder te verdiepen en de focus te leggen op de verdeling van de microbiële data op een specifieke taxonomische rang, kan het nuttig zijn om de gegevens samen te voegen tot dat specifieke niveau. De functie agglomerateByRank vereenvoudigt dit proces en maakt meer geraffineerde en effectieve analyses mogelijk. Hier volgt een voorbeeld:

tse.agglomerated <- agglomerateByRank(tse, rank='Phylum')

# Check
datatable(data.frame(rowData(tse.agglomerated)),options = list(pageLength = 5),rownames = FALSE)

Perfect! Nu bevatten onze gegevens alleen nog maar taxonomische informatie tot op het niveau van het phylum, waardoor het gemakkelijker is om de nadruk te leggen op deze specifieke rang bij het analyseren van de data.

20.5 Metingen

20.5.1 Microbiële diversititeit

Microbiële diversititeit in microbiologie wordt gemeten op vershillende manieren:

  • Soortenrijkdom: Het totale aantal soorten micro-organismen.
  • Evenwichtigheid: De verdeling van soorten binnen een microbioom.
  • Diversiteit: De combinatie van beide (soortenrijkdom en evenwichtigheid).

Hill (1910)’s coefficiënt combineert deze soorten metingen tot een formule. De drie vorige maatstaven worden ook wel Alfabetische diversiteit (alpha-diversiteit) genoemd.

# Schatting (waargenomen) rijkdom
tse_alpha <- estimateRichness(tse, 
                             assay.type = "counts", 
                             index = "observed", 
                             name="observed")

# Controleer enkele van de eerste waarden in colData
head(tse_alpha$observed)
##  [1] 68 51 68 62 58 61

Het resultaat toont de geschatte rijkdomwaarden voor verschillende monsters of locaties binnen de dataset. Het geeft een idee van hoe divers elk monster is in verhouding tot het aantal verschillende soorten dat aanwezig is. We kunnen dan vervolgens een figuur tekenen om dit te visualiseren.

plotColData(tse_alpha, 
            "observed", 
            "cohort", 
            colour_by = "patient_status") +
  theme(axis.text.x = element_text(angle=45,hjust=1)) + 
  labs(y=expression(Richness[Observed]))

Om nog een stap verder te gaan, kunnen we ook de geschatte Shannon-index vergelijken met de waargenomen soortenrijkdom. De Shannon-index kwantificeert de diversiteit in relatie tot zowel het aantal verschillende soorten (rijkdom) als de gelijkheid van hun verspreiding (evenwichtigheid) en wordt als volgt berekend:

\[ H' = -\sum_{i=1}^{R} p_i \ln(p_i) \] is het aandeel dat bestaat uit een bepaald micro-organisme binnen een microbioom.


Eerst kunnen we deze maatstaf eenvoudig berekenen en toevoegen aan onze TSE.

tse_alpha <- estimateDiversity(tse_alpha, 
                              assay.type = "counts",
                              index = c("shannon"), 
                              name = c("shannon"))

En daarna kunnen we de twee maten van diversiteit vergelijken door de volgende grafieken te maken.

# Initialisatie van het grafiek object
plots <- lapply(c("observed", "shannon"),
                plotColData,
                object = tse_alpha,
                x = "patient_status",
                colour_by = "patient_status")

# Weergave verbeteren
plots <- lapply(plots, "+", 
                theme(axis.text.x = element_blank(),
                      axis.title.x = element_blank(),
                      axis.ticks.x = element_blank()))

# Grafieken vertonen
(plots[[1]] | plots[[2]]) +
  plot_layout(guides = "collect")

Het is erg belangrijk om al deze vergelijkingen te maken om diversiteit te kwantificeren en monsters in onze gegevens te vergelijken met behulp van verschillende maatstaven. - Je kunt andere soorten vergelijkingen direct in het boek vinden.


20.5.2 Community similarity (Gemeenschapsovereenkomst)

Community similarity of Gemeenschapsovereenkomst verwijst naar de mate waarin micro-organismen op elkaar lijken qua samenstelling en overvloed van verschillende microbiële taxa. Dit kan ons helpen begrijpen in hoeverre verschillende monsters op elkaar lijken en faciliteert het helpen van belangrijke informatie. In microbiële analyse is het echter gebruikelijker om de ongelijkheid (Beta diversiteit) tussen twee monsters A en B te meten met behulp van de Bray-Curtis-formule, die als volgt wordt gedefinieerd:

\[ BC_{ij} = \frac{\sum_{k} |A_{k} - B_{k}|}{\sum_{k} (A_{k} + B_{k})} \]

Gelukkig biedt de mia pakket ons een eenvoudige manier om ten eerste de relatieve overvloed te berekenen en daarna de Bray-Curtis ongelijkheid. de relatieve overvloed kan worden toegevoegd aan onze TSE met behulp van de transformAssay methode:

tse <- transformAssay(tse,
                      assay.type = "counts",
                      method = "relabundance")

Dit resulteert in een matrix waarbij de verschillende monsters als rijen worden weergegeven en de overvloed ten opzichte van de monsters als kolommen. Deze nieuwe maatstaaf is makkelijk toegankelijk via de assays van de tse:

assay(tse, "relabundance")[5:10,1:10]
##                       A110      A12     A15      A19      A21    A23      A25
##  Akkermansia       0.03057 0.046595 0.07539 0.014894 0.013226 0.1282 0.040124
##  Bacteroides_3     0.00000 0.160112 0.00000 0.113619 0.096048 0.0000 0.047602
##  Parabacteroides_1 0.00000 0.005470 0.00000 0.003290 0.004409 0.0000 0.002280
##  Bacteroides_4     0.00000 0.089370 0.00000 0.019663 0.004566 0.0000 0.064654
##  Bacteroides_5     0.00000 0.066061 0.00000 0.013542 0.006928 0.0000 0.055079
##  Parabacteroides_2 0.00000 0.004632 0.00000 0.002907 0.005196 0.0000 0.002189
##                         A28      A29     A34
##  Akkermansia       0.035930 0.014108 0.07693
##  Bacteroides_3     0.075247 0.198646 0.00000
##  Parabacteroides_1 0.003240 0.004515 0.00000
##  Bacteroides_4     0.033574 0.134312 0.00000
##  Bacteroides_5     0.064792 0.132054 0.00000
##  Parabacteroides_2 0.002798 0.003386 0.00000

In ons geval bevat de assay 151 rijen en 27 kolommen. Zoveel kolommen en dus dimensies kunnen datavisualisatie belemmeren.

Om het verschil tussen de verschillende monsters te visualiseren, kunnen we een hoofdcomponentenanalyse uitvoeren op de nieuwe assay. Dit projecteert de Bray-curtis dimensies op een lagere ruimte met behoud van zoveel mogelijk variatie. De geprojecteerde waarden worden principale coördinaten genoemd. U kunt hier “Multidimensional Scaling” (n.d.) meer lezen over dit type analyse.

“Multidimensional Scaling.” n.d. https://en.wikipedia.org/wiki/Multidimensional_scaling#Types.
Oksanen, Jari, F. Guillaume Blanchet, Michael Friendly, Roeland Kindt, Pierre Legendre, Dan McGlinn, Peter R. Minchin, et al. 2020. Vegan: Community Ecology Package. https://CRAN.R-project.org/package=vegan.

MIA biedt geen directe manier om de dimensionaliteit te reduceren, maar we kunnen wel gebruik maken van Bioconductor’s scater pakket en het vegan pakket, dat Oksanen et al. (2020) hier kan worden gevonden om de ongelijkheid om te zetten in werkelijke afstanden die gevisualiseerd kunnen worden:

# Voer een Hoofdcomponentenanalyse uit  op de relabundance assay en behoudt de Bray-Curtis afstanden.
tse <- runMDS(tse,
              FUN = vegdist,
              method = "bray",
              assay.type = "relabundance",
              name = "MDS_bray")

Nu we de hoofdcoördinaten hebben berekend, kunnen we ze als volgt weergeven in een tweedimensionale ruimte:

# Maak een ggplot object
p <- plotReducedDim(tse, "MDS_bray",colour_by = "cohort")

# Converteren naar een interactief plot met ggplotly
ggplotly(p)

De assen zijn echter niet erg informatief en de hoeveelheid behouden variantie door het algoritme is nergens te vinden. We kunnen de grafiek op de volgende manier aanpassen om meer informatie weer te geven :

# Berekent de behouden variantie
e <- attr(reducedDim(tse, "MDS_bray"), "eig")
rel_eig <- e / sum(e[e > 0])

# voegt de variantie toe aan de assen van de grafiek
p <- p + labs(x = paste("Component 1 (", round(100 * rel_eig[[1]], 1), "%", ")", sep = ""),
              y = paste("Component 2 (", round(100 * rel_eig[[2]], 1), "%", ")", sep = ""))

# Reonvert to an interactive plot with ggplotly
ggplotly(p)

Elke as toont nu de hoeveelheid variantie, in ons geval ongelijkheid, van elk hoofdcoördinaat. Je kunt meer opties toevoegen om bijvoorbeeld een bepaald kenmerk in te kleuren. Meer hierover vindt u in deze sectie Chapter 7 van het OMA boek.


20.6 Datavisualisatie met heatmaps

Heatmaps zijn een van de meest veelzijdige manieren om je gegevens te visualiseren. In dit gedeelte behandelen we hoe je een eenvoudige heatmap maakt om de meest voorkomende taxa te visualiseren met behulp van het sechm pakket. Ga voor een meer gedetailleerde heatmap naar dit gedeelteChapter 12.

Laten we de TreeSE subsetten naar de meest voorkomende taxa met behulp van een alternatief experiment:

altExp(tse, "prevalence-subset") <- subsetByPrevalent(tse,prevalence=0.5)[1:5,]

Bij het subsetten met deze functie bevat het resulterende object niet langer de juiste relatieve abundanties, omdat deze abundanties oorspronkelijk werden berekend op basis van de volledige dataset en niet op basis van de subset. Daardoor moeten we de waarden opnieuw berekenen om de subset accuraat te kunnen weergeven door middel van een heatmap. Omwille van de leesbaarheid subsetten we ook de eerste vijf taxa na de eerste subset.

altExp(tse, "prevalence-subset") <- transformAssay(altExp(tse,                                                "prevalence-subset"),
                assay.type = "counts",
                method = "relabundance")

Nu we de gegevens hebben voorbereid, kunnen we de eerder geladen sechm-bibliotheek gebruiken om de heatmap weer te geven:

# Definieert de kleuren.
setSechmOption("hmcols", value=c("#F0F0FF","#007562"))

# Geeft de daadwerkelijke heatmap weer.
sechm(altExp(tse, "prevalence-subset"), features =
      rownames(rowData(altExp(tse, "prevalence-subset"))),
      assayName="relabundance",show_colnames=TRUE)

In de heatmap hierboven valt op dat Parabacteroides relatief vaak voorkomen in sommige monsters terwijl Akkermansia zeer weinig wordt gedetecteerd.

Back to top