11  Applications interactives avec Shiny

11.1 Introduction

Shiny permet de créer des applications web interactives entièrement en R : l’utilisateur manipule des entrées (listes, curseurs, filtres) et voit statistiques et graphiques se mettre à jour. Ce chapitre couvre la structure UI/serveur, la réactivité, la validation, un mini tableau de bord et l’application fournie dans shiny-app/.

11.2 Objectifs pédagogiques

  • Expliquer l’architecture d’une app Shiny
  • Créer entrées, sorties et réactivité
  • Filtrer des données et afficher graphiques / tables
  • Valider les entrées et organiser le code
  • Lancer l’application locale du projet

11.3 Prérequis

Chapter 8 et bases de Chapter 6. Package shiny installé.

shiny_ok <- requireNamespace("shiny", quietly = TRUE)
message("shiny disponible : ", shiny_ok)
Exécution dans le livre

Les applications Shiny se lancent dans une session interactive. Les chunks ci-dessous sont surtout illustratifs (eval=FALSE) ; utilisez shiny-app/app.R pour tester réellement.

11.4 Présentation de Shiny

Shiny = interface (HTML/CSS/JS générés) + logique R. Idéal pour explorateurs de données, calculateurs et tableaux de bord internes.

11.5 Structure d’une application

Deux styles :

  1. Fichiers ui.R + server.R
  2. Fichier unique app.R (recommandé pour débuter)
library(shiny)

ui <- fluidPage(
  titlePanel("Titre"),
  sidebarLayout(
    sidebarPanel(/* entrées */),
    mainPanel(/* sorties */)
  )
)

server <- function(input, output, session) {
  # logique
}

shinyApp(ui, server)

11.6 Interface utilisateur et serveur

  • UI : ce que l’utilisateur voit et manipule (inputId)
  • Serveur : calcule output à partir de input via des fonctions render*

11.7 Entrées utilisateur

Fonction Usage
selectInput liste déroulante
sliderInput curseur numérique
checkboxInput case à cocher
dateRangeInput période
textInput texte libre

11.8 Sorties

render* *Output
renderPlot plotOutput
renderTable / renderDataTable tableOutput / dataTableOutput
renderText / renderPrint textOutput / verbatimTextOutput

11.9 Réactivité

donnees_filtrees <- reactive({
  req(input$region)
  ventes |> filter(region == input$region)
})

output$resume <- renderPrint({
  summary(donnees_filtrees()$montant)
})
  • reactive() : expression mise en cache, recalculée si dépendances changent
  • req() : attend qu’une entrée soit disponible
  • observe() / observeEvent() : effets de bord (pas de valeur de retour)

11.10 Filtres et graphiques interactifs

Voir l’application complète ci-dessous : choix du jeu de données, filtre, histogramme et résumé.

11.11 Validation des entrées

output$plot <- renderPlot({
  validate(
    need(input$variable != "", "Choisissez une variable")
  )
  # ...
})

11.12 Organisation du code

shiny-app/
├── app.R           # UI + server
├── R/              # fonctions auxiliaires (optionnel)
└── data/           # ou accès à ../data

Pour la production : modules Shiny, tests, logs.

11.13 Lancement local

shiny::runApp("shiny-app")
# ou ouvrir app.R dans RStudio et cliquer Run App
Rscript -e "shiny::runApp('shiny-app', launch.browser = TRUE)"

11.14 Tableau de bord simple — application du projet

L’application shiny-app/app.R permet de :

  1. Choisir un jeu : ventes, démographie ou météo
  2. Filtrer une catégorie (région / ville / mois)
  3. Afficher résumé numérique + histogramme + aperçu tabulaire

11.15 Introduction au déploiement

Cible Idée
Local runApp
shinyapps.io compte Posit, rsconnect::deployApp
Serveur Docker / Posit Connect IT interne

Ne déployez pas de données sensibles sans contrôle d’accès.

11.16 Exemple minimal exécutable (concept)

library(shiny)
library(ggplot2)

ui <- fluidPage(
  titlePanel("Histo mtcars"),
  selectInput("var", "Variable", choices = names(mtcars)),
  plotOutput("hist")
)

server <- function(input, output, session) {
  output$hist <- renderPlot({
    ggplot(mtcars, aes(.data[[input$var]])) +
      geom_histogram(bins = 15, fill = "#1a5276", color = "white") +
      theme_minimal()
  })
}

# shinyApp(ui, server)

11.17 Erreurs fréquentes

Erreur Cause Remède
Sortie vide Oubli de output$ / render* Vérifier les IDs identiques UI/serveur
Non-réactif Lecture input hors reactive Envelopper dans reactive/render
Chemin data Mauvais working directory Chemins relatifs à app.R
App qui ne démarre pas Package manquant install.packages("shiny")

11.18 Exercices

11.18.1 Niveau 1

  1. Quelle différence entre UI et serveur ?
  2. Citez deux *Input et deux *Output.

11.18.2 Niveau 2

  1. Lancez shiny-app et changez de jeu de données.
  2. Modifiez le nombre de bins de l’histogramme (ajoutez un sliderInput).

11.18.3 Niveau 3

  1. Ajoutez un downloadButton pour exporter le tableau filtré en CSV.
  2. Factorisez le code de filtrage dans une fonction filtrer_donnees().

11.19 Corrections (indications)

# sliderInput("bins", "Nombre de classes", min = 5, max = 40, value = 15)
# geom_histogram(bins = input$bins, ...)

# downloadHandler(
#   filename = "extrait.csv",
#   content = function(file) readr::write_csv(donnees_filtrees(), file)
# )

11.20 Points clés

  • Shiny = UI + serveur + réactivité.
  • Gardez les calculs dans des reactive clairs.
  • Testez localement avant tout déploiement.

11.21 Ressources

11.22 Suite

Chapter 12 : projets de synthèse et évaluations.