diff --git a/server.R b/server.R index 5fe94a7f1fca9da79a8b48e300468a48165beda5..53e7d334058183657128ef9bfa9f97c3ef0280b3 100644 --- a/server.R +++ b/server.R @@ -27,7 +27,7 @@ shinyServer options = list( dom = "lBtip", pageLength = 10, - lengthMenu = list(c(10, 25, 50, 100, -1), list('10', '25', '50', '100', 'All')), + lengthMenu = list(c(10, 25, 50, 100,-1), list('10', '25', '50', '100', 'All')), buttons = list( 'colvis', list( @@ -45,9 +45,9 @@ shinyServer ) } - source( + source({ "https://raw.githubusercontent.com/mahendra-mariadassou/phyloseq-extended/master/R/load-extra-functions.R" - ) + }) data16S <- reactive({ if (input$demo != "input") @@ -122,6 +122,7 @@ shinyServer output$rarefactionMin <- renderText({ validate(need(input$fileBiom, ""), need(input$demo == "input", "")) paste("(min sample =", format(min(sample_sums(data16S( + ))), big.mark = " "), "reads)") }) @@ -129,7 +130,7 @@ shinyServer validate( need( data16S(), - "Merci de commencer par importer un fichier d'abondance au format BIOM. Celui-ci peut etre obtenu a l'issue du workflow FROGS avec l'operation 'FROGS BIOM to std BIOM'.\nVous pouvez egalement choisir un dataset de demo" + "Firsly, you should select a demo dataset or upload an abundance BIOM file.\nFor example, with Galaxy, this one can be obtained at the end of FROGS workflows with 'FROGS BIOM to std BIOM' tools" ) ) data16S() @@ -151,6 +152,7 @@ shinyServer data.frame(OTU = taxa_names(data16S()), tax_table(data16S())) )), tabPanel("sample_data", + #as.data.frame(sapply(sample_data(data16S()), class)), beautifulTable( data.frame(SAMPLE = sample_names(data16S()), sample_data(data16S())) )) @@ -161,23 +163,24 @@ shinyServer output$histUI <- renderUI({ validate(need(data16S(), "")) box( - title = "Paramètres", + title = "Setting : ", width = NULL, status = "primary", - selectInput( + radioButtons( "barFill", - label = "Niveau taxo :", - choices = rank_names(data16S()) + label = "Taxonomic rank : ", + choices = rank_names(data16S()), + inline = TRUE ), selectInput( "barGrid", - label = "Regroupement :", + label = "Subplot : ", choices = c("..." = 0, sample_variables(data16S())) ) , selectInput( "barX", - label = "X :", + label = "X : ", choices = c("..." = 0, sample_variables(data16S())) ) ) @@ -185,7 +188,7 @@ shinyServer output$histo <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) p <- plot_bar( physeq = data16S(), fill = input$barFill, @@ -202,7 +205,7 @@ shinyServer validate(need(data16S(), "")) radioButtons( "focusRank", - label = "Niveau taxo :", + label = "Taxonomic rank : ", choices = rank_names(data16S())[-length(rank_names(data16S()))], inline = TRUE ) @@ -212,7 +215,7 @@ shinyServer validate(need(data16S(), "")) selectInput( "focusTaxa", - label = "Taxa :", + label = "Selected taxa : ", choices = unique(as.vector(tax_table(data16S( ))[, input$focusRank])), @@ -224,11 +227,10 @@ shinyServer validate(need(data16S(), "")) sliderInput( "focusNbTaxa", - label = "Nombre de sous-taxons :", + label = "Number of sub-taxa : ", min = 0, #max = sum(tax_table(tax_glom(data16S(), rank_names(data16S())[1+as.integer(input$focusRank)]))[, as.integer(input$focusRank)]==input$focusTaxa) - max = 30 - , + max = 30, value = 10 ) }) @@ -236,20 +238,20 @@ shinyServer output$histFocusUIfocusGrid <- renderUI({ validate(need(data16S(), "")) selectInput("focusGrid", - label = "Regroupement :", + label = "Subplot : ", choices = c("..." = 0, sample_variables(data16S()))) }) output$histFocusUIfocusX <- renderUI({ validate(need(data16S(), "")) selectInput("focusX", - label = "X :", + label = "X : ", choices = c("..." = 0, sample_variables(data16S()))) }) output$histoFocus <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) p <- plot_composition( physeq = data16S(), taxaRank1 = input$focusRank, @@ -269,12 +271,12 @@ shinyServer output$clustUI <- renderUI({ validate(need(data16S(), "")) box( - title = "Paramètres", + title = "Setting : " , width = NULL, status = "primary", selectInput( "clustDist", - label = "Distance :", + label = "Distance : ", choices = list( "bray", "jaccard", @@ -287,7 +289,7 @@ shinyServer ), selectInput( "clustMethod", - label = "Methode :", + label = "Method : ", choices = list( "ward.D2", "ward.D", @@ -301,7 +303,7 @@ shinyServer ), selectInput( "clustCol", - label = "Couleur :", + label = "Color : ", choices = c("..." = 0, sample_variables(data16S())) ) ) @@ -309,7 +311,7 @@ shinyServer output$clust <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) plot_clust( physeq = data16S(), dist = input$clustDist, @@ -321,12 +323,12 @@ shinyServer output$richnessAUI <- renderUI({ validate(need(data16S(), "")) box( - title = "Paramètres", + title = "Setting : " , width = NULL, status = "primary", checkboxGroupInput( "richnessMeasures", - label = "Mesures :", + label = "Measures : ", choices = c( "Observed", "Chao1", @@ -349,26 +351,26 @@ shinyServer ), selectInput( "richnessX", - label = "X :", + label = "X : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "richnessColor", - label = "Couleur :", + label = "Color : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "richnessShape", - label = "Forme :", + label = "Shape : ", choices = c("..." = 0, sample_variables(data16S())) ), radioButtons( "richnessBoxplot", - label = "Representation :", + label = "Representation : ", choices = list( - "Points seuls" = 1, - "Boxplot et points" = 2, - "Boxplot seul" = 3 + "Dots only" = 1, + "Dots and boxplot" = 2, + "Boxplot only" = 3 ), selected = 2, inline = TRUE @@ -378,7 +380,7 @@ shinyServer output$richnessA <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) p <- plot_richness( physeq = data16S(), x = ifelse(is.null(checkNull( @@ -399,7 +401,7 @@ shinyServer output$richnessATable <- renderUI({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) p(beautifulTable(data.frame( SAMPLE = sample_names(data16S()), round(estimate_richness(data16S()), digits = 2) ))) @@ -407,12 +409,12 @@ shinyServer output$richnessBUI <- renderUI({ box( - title = "Paramètres", + title = "Setting : " , width = NULL, status = "primary", selectInput( "richnessOrder", - label = "Ordre de tri des echantillons :", + label = "Sorting sample : ", choices = c("..." = 0, sample_variables(data16S())) ) ) @@ -420,7 +422,7 @@ shinyServer output$richnessB <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) beta <- melt(as(distance(data16S(), method = input$richnessBDist), "matrix")) colnames(beta) <- c("x", "y", "distance") @@ -454,32 +456,32 @@ shinyServer output$networkBUI <- renderUI({ validate(need(data16S(), "")) box( - title = "Paramètres", + title = "Setting : " , width = NULL, status = "primary", sliderInput( "netwMax", - label = "Cutoff :", + label = "Threshold : ", min = 0, max = 1, value = 0.7 ), checkboxInput("netwOrphan", - label = "Garder les points orphelins", + label = "Keep orphans", value = TRUE), selectInput( "netwCol", - label = "Couleur :", + label = "Color : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "netwShape", - label = "Forme :", + label = "Shape : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "netwLabel", - label = "Label :", + label = "Label : ", choices = c( "..." = 0, "Sample name" = "value", @@ -491,7 +493,7 @@ shinyServer output$networkB <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) g <- make_network( data16S(), distance = input$richnessBDist, @@ -512,7 +514,7 @@ shinyServer output$richnessBTable <- renderUI({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) p(beautifulTable(data.frame( SAMPLE = sample_names(data16S()), round(as.matrix( distance(data16S(), method = input$richnessBDist) @@ -522,7 +524,7 @@ shinyServer output$rarefactionCurve <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) p <- ggrare( physeq = data16S(), step = 100, @@ -546,25 +548,25 @@ shinyServer output$rarefactionCurveUI <- renderUI({ validate(need(data16S(), "")) box( - title = "Paramètres", + title = "Setting : " , width = NULL, status = "primary", # sliderInput( # "rarefactionStep", - # label = "Etapes de calcul :", + # label = "Etapes de calcul : ", # min = 1, # max = 1000, # value = 100 # ), - checkboxInput("rarefactionMin", label = "Afficher le seuil de l'echantillon minimal", value = FALSE), + checkboxInput("rarefactionMin", label = "Show min sample threshold", value = FALSE), selectInput( "rarefactionColor", - label = "Couleur :", + label = "Color : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "rarefactionGrid", - label = "Regroupement :", + label = "Subplot : ", choices = c("..." = 0, sample_variables(data16S())) ) ) @@ -573,29 +575,29 @@ shinyServer output$HeatmapUI <- renderUI({ validate(need(data16S(), "")) box( - title = "Paramètres", + title = "Setting : " , width = NULL, status = "primary", selectInput( "heatmapGrid", - label = "Regroupement :", + label = "Subplot : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "heatmapX", - label = "X :", + label = "X : ", choices = c("..." = 0, sample_variables(data16S())) ), sliderInput( "heatmapTopOtu", - label = "Selection des n OTU les plus abondant :", + label = "Show the n most abundant OTU : ", min = 1, max = ntaxa(data16S()), value = 250 ), selectInput( "heatmapDist", - label = "Distance :", + label = "Distance : ", selected = "bray", choices = list( "bray", @@ -609,7 +611,7 @@ shinyServer ), selectInput( "heatmapMethod", - label = "Methode :", + label = "Method : ", selected = "NMDS", choices = list( "NMDS", @@ -628,7 +630,7 @@ shinyServer output$Heatmap <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) p <- plot_heatmap( physeq = prune_taxa(names(sort( taxa_sums(data16S()), decreasing = TRUE @@ -650,12 +652,12 @@ shinyServer output$treeUI <- renderUI({ validate(need(data16S(), "")) box( - title = "Paramètres", + title = "Setting : " , width = NULL, status = "primary", radioButtons( "treeRank", - label = "Niveau taxonomique légendé :", + label = "Taxonomic rank captioned : ", choices = c(aucun = "", rank_names(data16S()), OTU = "taxa_names"), @@ -663,21 +665,21 @@ shinyServer ), sliderInput( "treeTopOtu", - label = "Selection des n OTU les plus abondant :", + label = "Show the n most abundant OTU : ", min = 1, max = ntaxa(data16S()), value = 20 ), - checkboxInput("treeRadial", label = "Arbre radial", value = FALSE), + checkboxInput("treeRadial", label = "Radial tree", value = FALSE), checkboxInput("treeSample", label = "Show samples", value = TRUE), selectInput( "treeCol", - label = "Couleur :", + label = "Color : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "treeShape", - label = "Forme :", + label = "Shape : ", choices = c("..." = 0, sample_variables(data16S())) ) ) @@ -685,10 +687,10 @@ shinyServer output$tree <- renderPlot({ validate( - need(data16S(), "Merci d'importer un fichier d'abondance"), + need(data16S(), "Need an abundance dataset"), need( phy_tree(data16S(), errorIfNULL = FALSE), - "Arbre phylo invalide" + "Need an phylogenetic tree" ) ) p <- plot_tree( @@ -714,12 +716,12 @@ shinyServer output$acpUI <- renderUI({ validate(need(data16S(), "")) box( - title = "Paramètres", + title = "Setting : " , width = NULL, status = "primary", selectInput( "acpDist", - label = "Distance :", + label = "Distance : ", selected = "bray", choices = list( "bray", @@ -733,33 +735,33 @@ shinyServer ), selectInput( "acpMethod", - label = "Methode :", + label = "Method : ", selected = "MDS", choices = list("DCA", "CCA", "RDA", "CAP", "DPCoA", "NMDS", "MDS", "PCoA") ), selectInput( "acpLabel", - label = "Label :", + label = "Label : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "acpCol", - label = "Couleur :", + label = "Color : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "acpShape", - label = "Forme :", + label = "Shape : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "acpEllipse", - label = "Ellipses :", + label = "Ellipses : ", choices = c("..." = 0, sample_variables(data16S())) ), selectInput( "acpRep", - label = "Barycentre :", + label = "Barycenters : ", choices = c("..." = 0, sample_variables(data16S())) ) ) @@ -767,7 +769,7 @@ shinyServer output$acp <- renderPlot({ validate(need(data16S(), - "Merci d'importer un fichier d'abondance")) + "Need an abundance dataset")) p <- plot_samples( data16S(), ordination = ordinate( diff --git a/ui.R b/ui.R index fa82fdf8898e3b37b51b9a5911dc1a24b80209a5..b9938b94b6b26a4596949591be96af6b8e3292da 100644 --- a/ui.R +++ b/ui.R @@ -3,177 +3,167 @@ shinyUI(dashboardPage( dashboardHeader(title = "Easy16S"), dashboardSidebar( tags$div( - title = "Load data for demo", + title = "Select dataset for demonstration", selectInput( "demo", - label = "Select demo data", + label = "Select demo dataset : ", choices = list("Input data" = "input", - "Chaillou et al., 2015" = "food"#, - # "Mach et al., 2015" = "kinetic", - # "Morton et al., 2017" = "soil", - # "Ravel et al., 2011" = "ravel", - #"GlobalPatterns" = "GlobalPatterns", - #"biorare"), - selected = 1 - ) - ), - hr(width = "90%"), - tags$div( - title = "Fichier d'abondance au format BIOM produit avec FROGS avec 'FROGS BIOM to std BIOM'", - fileInput( - "fileBiom", - label = h4("Fichier d'abondance :"), - placeholder = "data.biom" - ), - radioButtons( - "biomFormat", - label = NULL, - inline = TRUE, - choices = list(`STD BIOM` = "std", - `FROGS BIOM` = "frogs"), - selected = "std" - ) + "Chaillou et al., 2015" = "food"), + # "Mach et al., 2015" = "kinetic", "Morton et al., 2017" = "soil", "Ravel et al., 2011" = "ravel", "biorare" = "biorare", "GlobalPatterns" = "GlobalPatterns" + selected = 1 + ) + ), + hr(width = "90%"), + tags$div( + title = "Abundance BIOM file come from FROGS with 'FROGS BIOM to std BIOM', Qiime or another metagenomic tool.", + fileInput("fileBiom", + label = "Abundance BIOM file : ", + placeholder = "data.biom"), + radioButtons( + "biomFormat", + label = NULL, + inline = TRUE, + choices = list(`STD BIOM` = "std", + `FROGS BIOM` = "frogs"), + selected = "std" + ) + ), + tags$div( + style = "text-align:center", + title = "Resample dataset such that all samples have the same library size. \nIt's using an random sampling without replacement.", + checkboxInput("rareData", label = "Rarefy dataset", value = TRUE), + textOutput("rarefactionMin") + ), + tags$div( + title = "Metadata table with variables (in columns) and samples (in rows). \nMake sure you follow the exact spelling of the sample names (1st column). \nThe import of an excel table is possible but not recommended.", + fileInput("fileMeta", + label = "Metadata table : ", + placeholder = "data.csv") + ), + radioButtons( + "CSVsep", + label = "CSV separator : ", + inline = TRUE, + choices = list( + `<tab>` = "\t", + `,` = ",", + `;` = ";", + excel = "excel" + ) + ), + tags$div( + title = "Phylogenetic tree", + fileInput("fileTree", + label = "Phylogenetic tree : ", + placeholder = "data.nwk") + )#, + # tags$div( + # title = "Representative FASTA sequences of OTU", + # fileInput( + # "fileSeq", + # label = "FASTA sequences : "), + # placeholder = "data.fasta" + # ) + # ) + ), + dashboardBody( + tabsetPanel( + tabPanel( + "Summary", + verbatimTextOutput("phyloseqPrint"), + uiOutput("summaryTable") ), - tags$div( - style = "text-align:center", - title = "Rarefier les données avec un tirage aléatoire pour supprimer l'effet de la profondeur de séquençage", - checkboxInput("rareData", label = "Rarefier les donnees.", value = TRUE), - textOutput("rarefactionMin") + tabPanel( + "Global barplot", + plotOutput("histo", height = 700), + uiOutput("histUI") ), - tags$div( - title = "Tableau de métadonnées avec en colonne les variables, en ligne les échantillons. \nAssurez vous de bien respecter l'ortographe des noms d'échantillons (1ère colonne). \nL'import d'une table excel est possible mais déconseillé.", - fileInput( - "fileMeta", - label = h4("Metadata :"), - placeholder = "data.csv" + tabPanel( + "Focus barplot", + plotOutput("histoFocus", height = 700), + box( + title = "Paramètres", + width = NULL, + status = "primary", + uiOutput("histFocusUIfocusRank"), + uiOutput("histFocusUIfocusTaxa"), + uiOutput("histFocusUIfocusNbTaxa"), + uiOutput("histFocusUIfocusGrid"), + uiOutput("histFocusUIfocusX") ) ), - radioButtons( - "CSVsep", - label = "CSV Séparateur", - inline = TRUE, - choices = list( - `<tab>` = "\t", - `,` = ",", - `;` = ";", - excel = "excel" - ) + tabPanel( + "Clustering", + plotOutput("clust", height = 700), + uiOutput("clustUI") ), - tags$div( - title = "Arbre phylogéniques des OTU enracinné", - fileInput( - "fileTree", - label = h4("Arbre :"), - placeholder = "data.nwk" - ) - )#, - # tags$div( - # title = "Séquences FASTA des OTU", - # fileInput( - # "fileSeq", - # label = h4("Séquences de references :"), - # placeholder = "data.fasta" - # ) - # ) - ), - dashboardBody( - tabsetPanel( - tabPanel( - "Summary", - verbatimTextOutput("phyloseqPrint"), - uiOutput("summaryTable") - ), - tabPanel( - "Histo global", - plotOutput("histo", height = 700), - uiOutput("histUI") - ), - tabPanel( - "Histo selectif", - plotOutput("histoFocus", height = 700), - box( - title = "Paramètres", - width = NULL, - status = "primary", - uiOutput("histFocusUIfocusRank"), - uiOutput("histFocusUIfocusTaxa"), - uiOutput("histFocusUIfocusNbTaxa"), - uiOutput("histFocusUIfocusGrid"), - uiOutput("histFocusUIfocusX") + tabPanel(HTML("α-diversity"), + box( + width = NULL, tabsetPanel( + tabPanel( + "Plots", + plotOutput("richnessA", height = 700), + uiOutput("richnessAUI") + ), + tabPanel("Tables", uiOutput("richnessATable")) + ) + )), + tabPanel( + HTML("β-diversity"), + selectInput( + "richnessBDist", + label = "Distance : ", + choices = list( + "bray", + "jaccard", + "unifrac", + "wunifrac", + "dpcoa", + "jsd", + "euclidean" ) ), - tabPanel( - "Clustering", - plotOutput("clust", height = 700), - uiOutput("clustUI") - ), - tabPanel("Richesse alpha", box( - width = NULL, tabsetPanel( - tabPanel( - "Courbes", - plotOutput("richnessA", height = 700), - uiOutput("richnessAUI") - ), - tabPanel("Tables", uiOutput("richnessATable")) - ) - )), - tabPanel( - "Richesse beta", - selectInput( - "richnessBDist", - label = "Distance :", - choices = list( - "bray", - "jaccard", - "unifrac", - "wunifrac", - "dpcoa", - "jsd", - "euclidean" - ) + box(width = NULL, tabsetPanel( + tabPanel( + "Heatmap", + plotOutput("richnessB", height = 700), + uiOutput("richnessBUI") ), - box(width = NULL, tabsetPanel( - tabPanel( - "Heatmap", - plotOutput("richnessB", height = 700), - uiOutput("richnessBUI") - ), - tabPanel( - "Networks", - plotOutput("networkB", height = 700), - uiOutput("networkBUI") - ), - tabPanel("Tables", uiOutput("richnessBTable")) - )) - ), - tabPanel( - "Courbe de rarefaction", - plotOutput("rarefactionCurve", height = 700), - uiOutput("rarefactionCurveUI") - ), - tabPanel( - "Arbre phylo", - plotOutput("tree", height = 700), - uiOutput("treeUI") - ), - tabPanel( - "Heatmap", - plotOutput("Heatmap", height = 700), - uiOutput("HeatmapUI") - ), - tabPanel( - "Analyses multivariées", - plotOutput("acp", height = 700), - uiOutput("acpUI") - ), - tabPanel( - "et plus ...", - div( - "Merci d'adresser vos remarques, bugs, demandes, besoins et conseils à ", - a(href = "mailto:cedric.midoux@irstea.fr?subject=[Easy16S]", "cedric.midoux@irstea.fr") - ) + tabPanel( + "Networks", + plotOutput("networkB", height = 700), + uiOutput("networkBUI") + ), + tabPanel("Tables", uiOutput("richnessBTable")) + )) + ), + tabPanel( + "Rarefaction curves", + plotOutput("rarefactionCurve", height = 700), + uiOutput("rarefactionCurveUI") + ), + tabPanel( + "Phylogenetic tree", + plotOutput("tree", height = 700), + uiOutput("treeUI") + ), + tabPanel( + "Heatmap", + plotOutput("Heatmap", height = 700), + uiOutput("HeatmapUI") + ), + tabPanel( + "MultiDimensional Scaling", + plotOutput("acp", height = 700), + uiOutput("acpUI") + ), + tabPanel( + "News features ...", + div( + "Questions, problems or comments regarding this application should be sent to ", + a(href = "mailto:cedric.midoux@irstea.fr?subject=[Easy16S]", "cedric.midoux@irstea.fr") ) ) ) - )) - \ No newline at end of file + ) +))