2 votes

Lire un fichier RData dans une application Shiny

Je travaille sur une application brillante qui va lire quelques fichiers RData et afficher des tableaux avec leur contenu. Ces fichiers sont générés par des scripts qui transforment éventuellement les données en un cadre de données. Ils sont ensuite sauvegardés à l'aide de la fonction save().

Dans l'application shiny, j'ai trois fichiers :

ui.R, server.R, et global.R

Je veux que les fichiers soient lus à intervalles réguliers afin qu'ils soient mis à jour lorsque les fichiers sont mis à jour :

reactiveFileReader() 

J'ai suivi quelques-unes des instructions que j'ai trouvées en ligne, mais je continue à obtenir une erreur "Error : missing value where TRUE/FALSE is needed". J'ai essayé de simplifier les choses afin de ne pas utiliser :

reactiveFileReader() 

et le simple chargement du fichier dans le fichier server.R (également essayé dans le fichier global.R). Encore une fois, le

load()

lit un cadre de données. J'ai réussi à le faire fonctionner à un moment donné en chargeant le fichier, puis en assignant le fichier à une variable et en faisant un "as.data.table", mais cela ne devrait pas avoir d'importance, cela devrait lire dans un format de cadre de données très bien. Je pense qu'il s'agit d'un problème de champ d'application, mais je n'en suis pas sûr. Vous pouvez m'aider ? Mon code est à :

http://pastebin.com/V01Uw0se

Merci beaucoup !

8voto

warmoverflow Points 3295

Voici une solution possible inspirée par ce billet http://www.r-bloggers.com/safe-loading-of-rdata-files/ . Le fichier Rdata est chargé dans un nouvel environnement qui garantit qu'il n'aura pas d'effet secondaire inattendu (écrasement de variables existantes, etc.). Lorsque vous cliquez sur le bouton, un nouveau cadre de données aléatoires est généré et enregistré dans un fichier. Le reactiveFileReader lit alors le fichier dans un nouvel environnement. Enfin, nous accédons au premier élément du nouvel environnement (en supposant que le fichier Rdata ne contient qu'une seule variable qui est un cadre de données) et l'imprimons dans un tableau.

library(shiny)

# This function, borrowed from http://www.r-bloggers.com/safe-loading-of-rdata-files/, load the Rdata into a new environment to avoid side effects
LoadToEnvironment <- function(RData, env=new.env()) {
  load(RData, env)
  return(env)
}

ui <- shinyUI(fluidPage(

  titlePanel("Example"),

  sidebarLayout(
    sidebarPanel(
      actionButton("generate", "Click to generate an Rdata file")
    ),

    mainPanel(
      tableOutput("table")
    )
  )
))

server <- shinyServer(function(input, output, session) {

  # Click the button to generate a new random data frame and write to file
  observeEvent(input$generate, {
    sample_dataframe <- data.frame(a=runif(10), b=rnorm(10))
    save(sample_dataframe, file="test.Rdata")
    rm(sample_dataframe)
  })

  output$table <- renderTable({
    # Use a reactiveFileReader to read the file on change, and load the content into a new environment
    env <- reactiveFileReader(1000, session, "test.Rdata", LoadToEnvironment)
    # Access the first item in the new environment, assuming that the Rdata contains only 1 item which is a data frame
    env()[[names(env())[1]]]
  })

})

shinyApp(ui = ui, server = server)

1voto

azdatasci Points 182

Ok - J'ai trouvé comment faire ce dont j'ai besoin. Pour mon premier problème, je voulais l'aspect et la convivialité de 'renderDataTable', mais je voulais tirer dans un cadre de données (renderDataTable / dataTableOutput ne le permet pas, il doit être dans un format de tableau). Pour ce faire, j'ai trouvé une utilisation pratique de ReportingTools (de Bioconductor) et de la façon dont ils le font. Cela vous permet d'utiliser directement un cadre de données tout en ayant le tableau HTML avec les tris, la recherche, la pagination, etc. L'information peut être trouvée ici :

https://bioconductor.org/packages/release/bioc/html/ReportingTools.html

J'en viens maintenant à mon deuxième problème : la mise à jour régulière des données et du tableau sans redémarrer l'application. Cela s'est avéré simple, il m'a juste fallu un peu de temps pour le comprendre, étant nouveau dans Shiny. Une chose à souligner, pour garder cet exemple simple, j'ai utilisé renderTable plutôt que la solution ci-dessus avec le paquet ReportingTools. Je voulais simplement garder cet exemple simple. La première chose que j'ai faite est d'envelopper tout mon code server.R (dans la fonction shinyServer()) dans un observe({}). Ensuite, j'ai utilisé invalidateLater() pour lui dire de se rafraîchir toutes les 5 secondes. Voici le code :

## server.R ##
library(shiny)
library(shinydashboard)
library(DT)

shinyServer(function(input, output, session) {

  observe({

    invalidateLater(5000,session)

    output$PRI1LastPeriodTable <- renderTable({
      prioirtyOneIncidentsLastPeriod <- updateILP()
    })
  })
})

Maintenant, l'original pour la partie renderTable(), j'appelais juste le nom d'objet du fichier .Rdata chargé, mais je voulais qu'il soit lu à chaque fois, donc j'ai créé une fonction dans mon fichier global.R (cela aurait pu être dans server.R) pour charger le fichier. Ce code est ici :

updateILP <- function() {
  load(file = "W:/Projects/R/Scripts/ITPOD/itpod/data/prioirtyOneIncidentsLastPeriod.RData", envir = .GlobalEnv)
  return(prioirtyOneIncidentsLastPeriod)
}

C'est tout, rien d'autre ne va dans le fichier global.R. Votre fichier ui.R sera configuré comme vous le souhaitez, il appellera tableOutout, dataTableOutput, ou toute autre méthode de rendu dans l'interface utilisateur. Donc, ce qui se passe est que toutes les 5 secondes, le code renderTable() est lu toutes les 5 secondes, ce qui à son tour invoque la fonction qui lit réellement le fichier. J'ai testé cela en apportant des modifications au fichier de données, et la brillante application s'est mise à jour sans aucune interaction de ma part. Cela fonctionne comme un charme.

Si cette méthode est inélégante ou inefficace, faites-moi savoir si elle peut être améliorée, c'était la méthode la plus directe que j'ai trouvée. Merci à tous pour votre aide et vos commentaires !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X