Le package shiny
permet de développer très facilement des applications web à partir de R
. Grâce à cette librairie, et d’autres librairies R
dédiées comme ggplot2
et flexdashboard
, il est ainsi possible de générer des tableaux de bord, introduisant même des méthodes statistiques approfondies.
Pour notre premier TP, nous allons utiliser le jeu de données mtcars
présent sous R.
Une application quelle qu’elle soit fait intervenir des notions importantes à comprendre pour la suite :
Une application shiny
nécessite une organisation spécifique. Les fichiers doivent être nommés spécifiquement, et dans un répertoire déterminé. Les deux fichiers sont :
server.R
: définissant les opérations à réaliser (exécution) lors de la création de la page et lors des différentes interactions de l’utilisateur ;ui.R
: définissant l’interface utilisateur (UI signifiant User Interface), avec les différentes parties telles que le titre, les différentes boutons ou sélecteurs, et les graphiques et/ou textes.Il est aussi possible de n’avoir qu’un seul fichier. Dans ce cas, celui-ci doit s’appeler app.R
et contient les deux éléments ci-dessus.
Dans le répertoire peut aussi être présents des scripts R
classiques, des données au format RData
ou texte (ou autre), ainsi que tout ce qui est nécessaire à l’application.
Vous devez d’abord installer la librairie shiny
(cf TPs précédents). Il est possible de créer automatiquement une application via le menu, mais nous allons le faire manuellement afin de mieux comprendre le fonctionnement de la librairie.
Dans un nouveau répertoire créé spécifiquement, vous devez créer les deux fichiers R
avec strictement le contenu suivant :
server.R
:library(shiny)
shinyServer(function(input, output) {})
ui.R
:library(shiny)
shinyUI(fluidPage(
titlePanel("Première application")
))
Une fois ces fichiers enregistrés, pour voir le résultat, vous pouvez soit cliquer sur Run App
en haut à droite de l’éditeur de texte, soit exécuter la commande runApp()
dans la console. Vous devriez voir une fenêtre avec juste le titre qui s’affiche.
On va ajouter un nuage de points entre la variable mpg
(consommation en Miles/US Gallon) et wt
(poids) du jeu de données mtcars
. Il faut donc modifier les deux fichiers dont le contenu devient :
server.R
:library(shiny)
shinyServer(function(input, output) {
output$nuage <- renderPlot({
plot(mpg ~ wt, data = mtcars, main = "Consommation en fonction du poids")
})
})
ui.R
:library(shiny)
shinyUI(fluidPage(
titlePanel("Première application"),
plotOutput("nuage")
))
Que faut-il noter ?
nuage
qui sera une sortie graphique (plotOutput
) ;output$nuage
) comme étant un rendu graphique (renderPlot
), dans lequel on met du code R
permettant de faire un graphique. Le code ici présent est tou ) fait classique.On ajoute ici un bouton permettant de sélectionner la variable de l’axe \(x\) (wt
dans notre exemple). Nous allons laisser à l’utilisateur le choix entre wt
, hp
(puissance) et disp
(cylindrée). Il faut donc modifier les deux fichiers :
server.R
:library(shiny)
shinyServer(function(input, output) {
output$nuage <- renderPlot({
plot(mtcars$mpg ~ mtcars[,input$choix], main = "Consommation")
})
})
ui.R
:library(shiny)
shinyUI(fluidPage(
titlePanel("Première application"),
selectInput("choix", "Abscisse", c("wt", "hp", "disp")),
plotOutput("nuage")
))
Que faut-il noter ?
selectInput
) nommée choix
, avec un titre (Abscisse
) et donc une liste de choix (c("wt", "hp", "disp")
) ;input$choix
) sera une chaîne de caractère parmi les trois proposées. La commande mtcars[,input$choix]
renverra donc bien le vecteur de la colonne choisie par l’utilisateur.A tester : changer le titre de l’axe des abcisses pour afficher le nom de la variable choisie (cf paramètre xlab
dans la fonction plot
).
On souhaite ajouter maintenant le calcul automatique de la moyenne des deux variables sélectionnées. Pour cela, nous allons modifier le contenu des fichiers comme suit :
server.R
:library(shiny)
shinyServer(function(input, output) {
output$nuage <- renderPlot({
plot(mtcars$mpg ~ mtcars[,input$choix], main = "Consommation")
})
output$resumeMpg <- renderText({
paste("Moyenne mpg :", mean(mtcars$mpg, na.rm = T))
})
output$resumeVar <- renderText({
paste("Moyenne", input$choix, ":", mean(mtcars[,input$choix], na.rm = T))
})
})
ui.R
:library(shiny)
shinyUI(fluidPage(
titlePanel("Première application"),
selectInput("choix", "Abscisse", c("wt", "hp", "disp")),
plotOutput("nuage"),
textOutput("resumeMpg"),
textOutput("resumeVar")
))
Que faut-il noter ?
textOutput
), nommées resumeMpg
pour la moyenne de la consommation, et resumeVar
pour la moyenne de l’autre variable ;A tester : ajouter, dans le même esprit, le coefficient de corrélation entre les deux
On peut ajouter aussi des informations sous forme de tableau. Voici les nouveaux contenus à placer dans les fichiers :
server.R
:library(shiny)
shinyServer(function(input, output) {
output$nuage <- renderPlot({
plot(mtcars$mpg ~ mtcars[,input$choix], main = "Consommation")
})
output$resumeMpg <- renderText({
paste("Moyenne mpg :", mean(mtcars$mpg, na.rm = T))
})
output$resumeVar <- renderText({
paste("Moyenne", input$choix, ":", mean(mtcars[,input$choix], na.rm = T))
})
output$tableau <- renderTable({
sub = subset(mtcars, select = c("mpg", input$choix))
sapply(sub, summary)
})
})
ui.R
:library(shiny)
shinyUI(fluidPage(
titlePanel("Première application"),
selectInput("choix", "Abscisse", c("wt", "hp", "disp")),
plotOutput("nuage"),
textOutput("resumeMpg"),
textOutput("resumeVar"),
tableOutput("tableau")
))
Que faut-il noter ?
tableOutput
) ;renderTable
), celui-ci devant soit un data.frame
, soit un matrix
.A tester : utiliser dataTableOutput
et renderDataTable
à la place des deux fonctions ci-dessus, pour voir la différence de présentation.
La fonction sidebarLayout()
permet de prévoir une mise en page en deux zones :
On ne modifie ici que le fichier d’interface.
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("Première application"),
sidebarLayout(
sidebarPanel(
selectInput("choix", "Abscisse", c("wt", "hp", "disp")),
textOutput("resumeMpg"),
textOutput("resumeVar"),
tableOutput("tableau")
),
mainPanel(
plotOutput("nuage")
)
)
))
Que faut-il noter ?
sidebarLayout
permet donc de définir cette séparation en deux parties (environ 1/3-2/3). Elle doit contenir deux choses :sidebarPanel
qui contient les éléments qui seront donc à gauche par défautmainPanel
qui sera celle à droite et prenant le plus de placesidebarPanel
à droite avec sidebarLayout(position = "right", ..., ...)
A tester :
sidebarPanel
) à droiteDans la partie interface, il est possible de créer un système d’onglet permettant d’avoir plusieurs parties dans l’application. Voici la nouvelle partie interface utilisateur (ui.R
). Vous verrez ainsi le fonctionnement des onglets.
library(shiny)
shinyUI(fluidPage(
titlePanel("Première application"),
tabsetPanel(
tabPanel("Panel1",
titlePanel("titre Panel 1"),
# Travail fait précédemment
sidebarLayout(
sidebarPanel(
selectInput("choix", "Abscisse", c("wt", "hp", "disp")),
textOutput("resumeMpg"),
textOutput("resumeVar"),
tableOutput("tableau")
),
mainPanel(
plotOutput("nuage")
)
)
),
tabPanel("Panel2",
titlePanel("titre Panel 2")
# autre chose
)
# autres onglets possibles
)
))
Vous devez donc continuer l’application, avec le contenu suivant :
cyl
, vs
, am
, gear
et carb