R shiny utiliser des reactivedataframe

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

Pierre-Guy Sauriau
Messages : 4
Enregistré le : 22 Nov 2018, 21:18

R shiny utiliser des reactivedataframe

Messagepar Pierre-Guy Sauriau » 23 Nov 2018, 22:52

Bonjour,
Je modifie un script issu de R Shiny concernant la sélection de point sur un graphe et exclusion des points sélectionnés du fichier
renvoyé dans un reactive.
Le script utilise le dataframe "mcars" et le code est ci-dessous.
Ma question : comment adapter ce script pour que le dataframe en entrée dbinit <- mtcars soit lui même un reactive dataframe
qui sera lui même déjà utilisé par ailleurs pour des tests statistiques sur les différentes varaibles.
Je dois mal comprendre la syntaxe des reactive et reactivevalues ou bien ignorer certaines fonctions.
Il se peut que le forum ai déjà répondu en partie à cette interrogation merci alors d'éclairer ma lanterne.

Code : Tout sélectionner


# Research
# https://datascience.stackexchange.com/questions/5326/how-to-read-file-from-user-in-shiny-and-assign-it-to-a-variable-in-global-r

library(shiny)
library(ggplot2)
cat("\014")  ; rm(list=ls())
# Utilisation daframe mtcars / exemple dans ggplot2
# Ajout col : colone de couleur
# dbinit : prévu pour être reactive dataframe data initiales
# dbselect : prévu pour être reactive dataframe data finales

dbinit <- mtcars
dbselect <- c()
dbinit$col <- "black"

ui <- fluidPage(
     p("Pour exclure un/des points, dessiner un rectangle autour du/des points et valider le bouton Exclusion"),
     p("Pour annuler une ou plusieurs exclusions, redessiner le rectangle autour du/des points et valider le bouton Exclusion"),
     p("Pour tout annuler, bouton Annulation")
     ,
     plotOutput("plot1_3", brush = brushOpts(id = "plot1_brush", fill="red", resetOnNew=TRUE)),
     actionButton("exclude_toggle", "Exclusion des points entourés", icon("window-close"),
                        style="color: #fff; background-color: red; border-color: black"),
     actionButton("exclude_reset", "Annulation", icon("sync"),
                        style="color: #000080; background-color: #E0FFFF; border-color: black"),
     plotOutput("plot1_4")
     )

server <- function(input, output) {
 
  # For storing which rows have been excluded
  vals <- reactiveValues(keeprows = rep(TRUE, nrow(dbinit)))
 
  output$plot1_3 <- renderPlot({
    # Plot the kept and excluded points as two separate data sets
    keep    <- dbinit[ vals$keeprows, , drop = FALSE]
    exclude <- dbinit[!vals$keeprows, , drop = FALSE]
    if (nrow(exclude)>0) {
      exclude$col <- "red"
                         }
    ggplot(keep, aes(x= wt , y= mpg)) + geom_point(color = keep$col) +
      geom_smooth(method = lm, fullrange = TRUE, color = "black") +
      geom_point(data = exclude, shape = 21, fill = "red", color = exclude$col)
  })
    # Plot the final data sets
    output$plot1_4 <- renderPlot({
     keep    <- dbinit[ vals$keeprows, , drop = FALSE]
     keep$col <- "green"
     ggplot(keep, aes(wt , y = mpg)) + geom_point(color = keep$col) +
     geom_smooth(method = lm, fullrange = TRUE, color = "black")
  })

    # Toggle points that are brushed, when button is clicked
    observeEvent(input$exclude_toggle, {
    res <- brushedPoints(dbinit, input$plot1_brush, allRows = TRUE)
    # fonction xor compare les 2 dataframes et modifie le vals$keeprows
    vals$keeprows <- xor(vals$keeprows, res$selected_)
    #observe(cat(str(vals$keeprows)))
  })
 
  # Reset all points
  observeEvent(input$exclude_reset, {
    vals$keeprows <- rep(TRUE, nrow(dbinit))
    #observe(cat(str(vals$keeprows)))
  })
 
  # Store selected rows # # Base on reply_01
  dbselect<- reactive({
    data2<- dbinit[ vals$keeprows, , drop = FALSE]
    data2$col <- "green"
    data2
                     })
 
  # Observe wich rows have been selected
  observe({print(vals$keeprows)})
  observe({print(dbselect())})
 
  # output$contents <- renderText({   
  #   data2<- dbinit[ vals$keeprows, , drop = FALSE]
  #   observe(cat(str(data2)))
  #   #assign('dbselect',data2,envir=.GlobalEnv)
  #})
 
}

shinyApp(ui, server)


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

Re: R shiny utiliser des reactivedataframe

Messagepar Pierre-Yves Berrard » 26 Nov 2018, 13:39

Bonjour,

Je ne connais pas la terminologie "reactivedataframe".
S'agit-il d'un data.frame dont le contenu va dépendre d'un ou plusieurs widgets de l'interface utilisateur ?
PY

Pierre-Guy Sauriau
Messages : 4
Enregistré le : 22 Nov 2018, 21:18

Re: R shiny utiliser des reactivedataframe

Messagepar Pierre-Guy Sauriau » 26 Nov 2018, 14:12

Oui c'est cela, j'ai essayé avec l'écriture dbinit() mais cela ne fonctionne pas.

vals <- reactiveValues(keeprows = rep(TRUE, nrow( dbinit() )))

retourne une erreur.

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

Re: R shiny utiliser des reactivedataframe

Messagepar Pierre-Yves Berrard » 26 Nov 2018, 14:39

Pour écrire dbinit(), il faut que dbinit soit une expression réactive créée par reactive(). Cette instruction doit être placée dans la partie server.

Difficile d'aider plus dans la mesure où on ne sait pas à partir de quels widgets va être construit ce data.frame...
PY

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

Re: R shiny utiliser des reactivedataframe

Messagepar Mickael Canouil » 27 Nov 2018, 09:32

Bonjour,

pour ajouter un peu plus:

Il suffit de créer l'objet dbinit en tant qu'objet "reactive" avec dans le paramètre "expr", ce que vous voulez faire et renvoyer en sortie:

Code : Tout sélectionner

dbinit <- reactive({
   # whatever you want to do
   return(mtcars)
})

Une fois fait, vous avez un objet "dbinit" qui contient mtcars, et accessible via "dbinit()"
Faute d’information plus détaillés/concrètes, c'est difficile d'en dire plus.
Au passage, je vous suggère d'aller visiter le site officiel (Rstudio) du package Shiny, vous trouverez des exemples (Section "Reactive programming", https://shiny.rstudio.com/gallery/), des tutoriaux, etc.

Exemple:

Code : Tout sélectionner

library(shiny)
ui <- fluidPage(
  mainPanel(
    selectInput(inputId = "dataset", label = "Choose a dataset:", choices = c("mtcars", "cars")),
    tableOutput("view")
  )
)

server <- function(input, output) {
  dbinit <- reactive(x = {
    switch(
      EXPR = input$dataset,
      "mtcars" = mtcars,
      "cars" = cars
    )
  })
  output$view <- renderTable(expr = {head(dbinit())})
}

shinyApp(ui, server)


Cordialement,
Mickaël

Pierre-Guy Sauriau
Messages : 4
Enregistré le : 22 Nov 2018, 21:18

Re: R shiny utiliser des reactivedataframe

Messagepar Pierre-Guy Sauriau » 27 Nov 2018, 11:41

Bonjour,
Merci beaucoup, je pense avoir saisi comment faire sur l'exemple fourni.
Le contexte de ma question :
Je prévois d'introduire cette partie de code dans un script R shiny plus large traitant de données hydrologiques.
L'idée de supprimer des valeurs sur un graphe est intéressante pour la gestion de valeurs potentiellement aberrantes
qui ne sont pas des erreurs de mesure (l'opérateur analyste suit une procédure de qualification) mais des points singuliers peut être révélateur de phénomènes biologiques.
L'utilisateur écarte cependant ces valeurs du jeu de données (une série chronologique) afin de poursuivre ses analyses statistiques (par exemple des corrélations très sensibles aux valeurs singulières) et pourra ultérieurement qualifier ces données de douteuses.

Bien cordialement et merci encore de vos réponses précises.

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

Re: R shiny utiliser des reactivedataframe

Messagepar Mickael Canouil » 27 Nov 2018, 13:58

ohhhh
Je ne suis personnellement pas fan de cette idée => https://www.shinyapps.org/apps/p-hacker/
Mickaël

Pierre-Guy Sauriau
Messages : 4
Enregistré le : 22 Nov 2018, 21:18

Re: R shiny utiliser des reactivedataframe

Messagepar Pierre-Guy Sauriau » 28 Nov 2018, 10:14

Je pensais à des cas plus triviaux, une valeur 10 fois plus élevée que le reste des valeurs
et que l'analyste chimique n'a pas écartée car l'analyse est conforme au protocole. Cela donne un nuage de points regroupés avec un point isolé.
En mode exploratoire, ce peut être utile de savoir ce qui se passe sans ce point isolé.
La détection de valeurs outliers moins "extrêmes" est un autre problème et je découvre l'application de Felix Schönbrodt.
dans le cas de Boxplot, nous utilisons des boxplot ajustés afin de traiter des distributions qui s'écartent de la loi normale
et ma question initiale a sans doute réponse dans le code de cette application.


Retourner vers « Questions en cours »

Qui est en ligne

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