1 Shiny, c’est parti !

  • Créer une application shiny avec RStudio File > New File > Shiny Web App.

  • Donner un nom à votre première application et enregistrer la dans le dossier de votre choix avec le choix “Single File”.

  • Parcourir et exécuter le code :

#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
#    http://shiny.rstudio.com/
#

library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Old Faithful Geyser Data"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30)
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("distPlot")
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

    output$distPlot <- renderPlot({
        # generate bins based on input$bins from ui.R
        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

app.R

2 Ajouter du texte

  • Sous la figure, ajouter une phrase précisant le nombre de bins.

app2.R

3 Choisir un titre

  • Ajouter un champs texte pour laisser à l’utilisateur le choix du titre de l’application titlePanel.

app3.R

4 Un peu de couleur

  • Ajouter des boutons radio permettant de choisir parmi les couleurs "darkgray", "coral", "lightgreen".

app4.R

5 Plusieurs onglets

  • Ajouter des onglets dans le mainPanel() avec l’aide de la fonction tabsetPanel()
    • le premier onglet : un histogramme
    • le second onglet : un boxplot
    • le troisième onglet : un tableau des données

app5.R

  • Changement de look pour notre application via l’utilisation d’un fichier CSS styles.css déposé dans le répertoire www
    • mettre en avant le titre de l’application en lui attribuant une couleur (darkblue par exemple)
    • mettre en avant les labels des éléments présents dans le sidebarPanel (purple par exemple)
    • distinguer davantage l’onglet sélectionné en changeant la couleur du texte (darkblue par exemple) et en passant le texte en gras (font-weight=bold)

app5_bis.R / styles.css

6 Un peu d’aléatoire

  • Actuellement, notre plot affiche les données des durées entre deux éruptions du geyser Old Faithful.
  • Remplacer les données par un tirage aléatoire de 10 valeurs x <- rnorm(10).
  • Que se passe-t-il lorsque l’on change la couleur du plot ? Est-ce que les différents onglets représentent les mêmes données ? Que proposez-vous pour résoudre cela ?

7 De nouvelles données

  • Actuellement, les données sont directement gérées au sein de la fonction du plot.
  • On va chercher à séparer le côté “données”, du côté “figures”.
  • Supprimer la ligne correspondante (x <- faithful[, 2]) de la fonction et la remplacer par un appel à l’expression réactive datasetInput() (x <- datasetInput()) qui permettra de gérer les données de manière dynamique et réactive. Avant le renderPlot, on définit l’expression réactive datasetInput tel que :
datasetInput <- reactive({faithful$waiting})
  • Tester l’application et vérifier que tout fonctionne toujours. Essayer de comprendre et d’assimiler l’articulation des différents éléments. > app6.R

  • Maintenant que tout est fonctionnel, à l’aide d’une liste déroulante, proposer le choix entre la durée des éruptions du geyser Old Faithful (faithful$waiting), la longueur des sépales des iris de Fisher (iris$Sepal.Length) ou la puissance des voitures d’après Motor Trend (mtcars$hp). Mettre mettre à jour datasetInput() en fonction de ce choix.

    • Note : on peut utiliser un enchaînement de else if ou bien la fonction switch.

app7.R

8 Des données générées aléatoirement

  • Ajouter un choix dans la liste correspondant à un tirage aléatoire de 100 valeurs distribuées normalement.
    • ajouter un champ dédié dans la liste déroulante
    • mettre à jour les données afin de renvoyer rnorm(100) si random est sélectionné dans le champ data.
  • Note : le reactive() ne dépend pas des inputs du choix de couleur ou du nombre de bins. Le tirage aléatoire ne change donc pas lorsque la couleur ou les bins sont modifiés.

app8.R

9 Paramètres du tirage aléatoire

  • Dans la barre de paramètres, ajouter une section dédiée aux paramètres du tirage (n, mean, sd).

  • Bonus : afficher ces paramètres uniquement lorsque l’on sélectionne les données aléatoires dans la liste déroulante (voir conditionalPanel, attention à la syntaxe).

  • Bonus : ajouter un bouton “Relancer” qui permet de relancer le tirage des données aléatoires lorsqu’on clique dessus.

  • Note : la solution proposée utilise des reactiveVal(), c’est à dire des variables réactives dont vous pouvez contrôler manuellement la mise à jour en plus de son caractère réactif (via un observeEvent() ou un observe() %>% bindEvent())

  • Bonus : remplacer le bouton “Relancer” par un bouton “Confirmer / Relancer” qui force l’utilisateur à confirmer son choix de paramètres (n, mean, sd) avant de générer les données aléatoires

  • Note : la stratégie possible consiste à utiliser 2 reactive() enchaînés (dont un soumis à un bindEvent()) et le choix apparaît clairement lorsqu’on trace le graphe de réactivité.

app9.R
app9_bis.R
app9_ter.R

10 Téléchargement de données

  • Permettre à l’utilisateur de charger ses données au format CSV.
    • ajouter un champ dédié dans la liste déroulante
    • ajouter un widget d’upload
    • Aide R : utiliser la fonction read.csv(file, header = FALSE)[,1] pour extraire la première colonne.
    • Note : input$file est un data.frame qui continent 4 éléments :
      • name : Le nom du fichier. Il ne s’aggit pas du chemin complet.
      • size : La taille du fichier téléchargé, en octets.
      • type : Le type du fichier ou un string vide si le navigateur ne le sait pas.
      • filepath: Le chemin d’accès à un fichier temporaire qui contient les données téléchargées. Ce fichier peut être supprimé si l’utilisateur effectue une autre opération de téléchargement. C’est cette variable qu’il faudra utiliser pour acédéer aux données.


  • Bonus : anticiper l’erreur du fichier non sélectionné avec les fonctions validate() et need() anisi que l’opérateur booléen OR ||

app10.R
app10bonus.R

11 Des data.frames et ggplot2 pour des graphiques élégants

  • ggplot2 comme de nombreux autres packages R utilise les dataframes. On va donc exploiter nos données avec ce format.
    • pour les données de démo faithful, iris et mtcars, ce sont des dataframes
    • pour les données chargées par l’utilisateur, il s’agit d’un dataframe avant que l’on extrait la première colonne
    • pour les données générées aléatoirement on va construire sous le format data.frame
  • Remplacer le reactive datasetInput par :
datasetInput <- reactive({
    switch(input$data,
           "faithful" = faithful,
           "iris" = iris,
           "mtcars" = mtcars,
           "random" = data.frame("rnorm" = rnorm(n = input$randomN, mean = input$randomMean, sd = input$randomSd)),
           "upload" = read.csv(input$file$datapath, header = TRUE))
})
  • Ajouter un widget varSelectInput destiné à sélectionner une variable
    • pour que ce widget se mette à jour en fonction des données choisies, il est nécessaire de le placer côté “server”.
    • pour l’afficher coté UI, on utilisera uiOutput qui renverra vers le renderUI associé où sera placé le widget.
  • Remplacer l’histogramme et le boxplot par l’équivalent en ggplot2. Le sujet du TP n’étant pas spécialement l’utilisation de ggplot2, voici directement les fonctions. Si vous êtes à l’aise, laissez libre cours à votre imagination pour les personnaliser.
    • Histogramme : ggplot(data = datasetInput(), aes_string(x = input$variable)) + geom_histogram(bins = input$bins, fill = input$color, color = "white")
    • Boxplot : ggplot(data = datasetInput(), aes_string(y = input$variable)) + geom_boxplot(fill = input$color)

app11.R

12 Téléchargement d’un plot

  • Ajouter un bouton pour télécharger le plot grâce aux fonctions downloadHandler et ggsave.

Note : pour que le téléchargement se lance correctement, lancer l’application dans un “vrai” navigateur. Utiliser la commande :

runApp('app11.R', launch.browser = TRUE) 

app12.R

13 Mise en forme avec CSS

  • On peut facilement mettre en forme l’interface utilisateur d’une application avec CSS (cascading style sheets).

    • choisir une feuille de style sur Bootswatch
    • télécharger le fichier bootstrap.css dans le dossier www/ de votre appli
    • indiquer le thème avec theme = "bootstrap.css" dans la fonction fluidPage()

app13.R avec un fichier bootstrap.css dans le dossier www/

14 Déploiement d’une application avec shinyapps.io

  • Créer un compte sur https://www.shinyapps.io/.
  • Définir un nom de domaine. Vos applications apparaîtront via https://<domaine>.shinyapps.io/<appli>/.
  • Rendez-vous sur la page d’administration et suivre les étapes afin de connecter votre RStudio local à votre compte grâce à rsconnect.
  • Cliquer sur l’icône Publish publish.
  • Sélectionner les fichiers à publier, définir un nom et cliquer sur “Publish”.
  • Note : Votre application doit s’appeler app.R ou bien ui.r+server.R.
  • C’est fini !
 

A work by Migale Bioinformatics Facility

https://migale.inrae.fr

Our two affiliations to cite us:

Université Paris-Saclay, INRAE, MaIAGE, 78350, Jouy-en-Josas, France

Université Paris-Saclay, INRAE, BioinfOmics, MIGALE bioinformatics facility, 78350, Jouy-en-Josas, France