Modularisation shiny

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

raphaelle legd
Messages : 3
Enregistré le : 19 Oct 2017, 10:58

Modularisation shiny

Messagepar raphaelle legd » 18 Oct 2021, 09:26

Bonjour à tous,

je travaille à la création d'une application shiny sont la structure est assez répétitive. Je souhaiterais modulariser certains bouts d'application (mais pas la totalité)

Voici un exemple générique, qui est le tracé d'un histogramme. Le choix de la variable à tracer (selectInput) doit être commune aux 2 graphiques. Le choix du nombre de bin et de la couleur du tracé ont été modularisés.

module histogramUI

Code : Tout sélectionner

histogramUI <- function(id) {
  tagList(
    numericInput(NS(id, "bins"), "bins", value = 10, min = 1),
    plotOutput(NS(id, "hist"))
  )
}


et son server histogramServer

Code : Tout sélectionner

histogramServer <- function(id,color) {
  moduleServer(id, function(input, output, session) {
    data <- reactive(mtcars[[input$var]])
    output$hist <- renderPlot({
      hist(data(), breaks = input$bins, main = input$var,col=color)
    }, res = 96)
  })
}


et le code ci dessous de l'application :

Code : Tout sélectionner

  ui <- fluidPage(
    selectInput("var", "Variable", choices = names(mtcars)),
    histogramUI("hist1"),
    histogramUI("hist2"),
  )
 
  server <- function(input, output, session) {
    histogramServer("hist1","blue")
   histogramServer("hist2","red")
  }
  shinyApp(ui, server) 


le code tel quel ne fonctionne pas, la valeur reactive input$var n'est visiblement pas prise en compte dans le module, l'erreur est la suivante :

Code : Tout sélectionner

 Error in .subset2: attempt to select less than one element in get1index



Que faudrait il faire ?

en vous remerciant d'avance de votre aide,

Sébastien Rochette
Messages : 54
Enregistré le : 03 Juil 2020, 12:43
Contact :

Re: Modularisation shiny

Messagepar Sébastien Rochette » 21 Oct 2021, 05:28

Bonjour,
D'abord, merci pour l'exemple reproductible.

L'input 'input$var' est créé en dehors du module, il n'est donc pas accessible au module. Il faut considérer les modules comme des fonctions indépendantes du reste du code. Ce qu'il se passe à l'intérieur, reste à l'intérieur. Et ce qu'il se passe à l'extérieur ne doit entrer que par un paramètre de la fonction de module. Comme une fonction classique.

Ici, vous avez besoin de créer un élément qui pourra se balader entre les modules. On utilise une 'reactiveValues()' pour que l'objet soit réactif aux changements de l'UI principale. Cette value devient un paramètre de la fonction de server du module, lisible dans un environnement réactif.
Chez nous, pour des questions de lisibilité, nous avons l'habitude de nommer les 'reactiveValues()' qui se déplacent entre modules: "global", et celle à l'intérieur des modules: "local".

Voici une proposition qui résout votre problème:

Code : Tout sélectionner

library(shiny)

histogramUI <- function(id) {
  ns <- NS(id)
  tagList(
    numericInput(ns("bins"), "bins", value = 10, min = 1),
    plotOutput(ns("hist"))
  )
}

histogramServer <- function(id, color, global) {
  moduleServer(id, function(input, output, session) {

    ns <- session$ns
    data <- reactive(mtcars[[global$var]])
    output$hist <- renderPlot({
      hist(data(), breaks = input$bins, main = global$var,col=color)
    }, res = 96)
  })
}

ui <- fluidPage(
  selectInput("var", "Variable", choices = names(mtcars)),
  histogramUI("hist1"),
  histogramUI("hist2"),
)

server <- function(input, output, session) {
  # Set a global reactiveValue to be used in your modules
  global <- reactiveValues()
  observeEvent(input$var, {global$var <- input$var})
 
  histogramServer("hist1", color = "blue", global = global)
  histogramServer("hist2", color = "red", global = global)
}
shinyApp(ui, server) 
Sébastien
Dev, Consult, Formateur
ThinkR

Franck Theeten
Messages : 17
Enregistré le : 07 Fév 2020, 17:09

Re: Modularisation shiny

Messagepar Franck Theeten » 24 Oct 2021, 21:25

EDIT: réponse erronée

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Modularisation shiny

Messagepar Mickael Canouil » 25 Oct 2021, 08:16

Franck Theeten a écrit :EDIT: réponse erronée

Cela veut dire quoi au juste ?
Mickaël
mickael.canouil.fr | rlille.fr

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Modularisation shiny

Messagepar Pierre-Yves Berrard » 25 Oct 2021, 09:28

Franck a posté une réponse dans le mauvais sujet, manifestement.
PY


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité