2013-06-24 6 views
10

Ist es möglich, Objekte in shiny zu laden, ohne dass eine separate redundante Instanz dieses Objekts innerhalb des Aufrufs downloadHandler() erstellt werden muss? Betrachten wir zum Beispiel das folgende Beispiel:Laden von reaktiven Objekten in Shiny

ui.R

library(shiny) 

shinyUI(pageWithSidebar(
    headerPanel("Simple Example"), 

    sidebarPanel(
    textInput("options","Enter some content:",""), 
    submitButton("Go") 
), 

    mainPanel(
    tableOutput("dataTable"), 
    downloadButton('downloadData','Save Data as CSV File') 
) 
)) 

server.R

library(shiny) 

shinyServer(function(input, output) { 
    makeQuery <- reactive({ 
     if(input$options == ""){ 
     return("Enter some options") 
     } 
     else { 
     return(input$options) 
     } 
    }) 

    runQuery <- function(query){ 
    dat <- data.frame(v1=rep(query,5)) 
    return(dat) 
    } 

    output$dataTable <- renderTable({ 
    query <- makeQuery() 
    if(grepl("^Enter",query)){ 
     return(data.frame(Error=query)) 
    } else { 
     return(runQuery(query)) 
    } 
    },include.rownames=FALSE) 

    output$downloadData <- downloadHandler(
    filename = c('data.csv'), 
    content = function(file) { 
     write.csv(runQuery(makeQuery()), file) 
    } 
) 

}) 

Das Problem, das ich mit dem obigen Beispiel ist, dass ich bin mit runQuery() innerhalb sowohl der renderTable() und downloadHandler() Anrufe. In diesem Beispiel gibt es keinen zusätzlichen Overhead, aber in meinem Beispiel muss ein 5- bis 10-minütiger Prozess ausgeführt werden, so dass es äußerst ineffizient ist, ihn zweimal aufzurufen, wenn jemand die Daten herunterlädt.

Gibt es trotzdem, dass ich dieses Problem umgehen kann, indem Sie auf ein bereits erstelltes Objekt im downloadHandler() Aufruf oder eine andere Arbeit verweisen?

+0

Kann Abfrage überhaupt beschleunigt werden? 'data.table' oder etwas? Ich glaube nicht, dass das Problem mit Download-Handler ist, wenn Ihre Abfragen so lange dauern. – intra

+0

Leider nicht - es ist eine Bienenstockabfrage zu einer Datenbank. – David

Antwort

16

Ja! Verwandeln Sie die Abfrage von einer Funktion, die Sie von zwei Stellen aufrufen, in einen reaktiven Ausdruck, auf den Sie von zwei Stellen aus zugreifen. Reaktive Ausdrücke speichern ihre Ergebnisse automatisch zwischen.

+0

Danke Joe! Ich habe gerade die Arbeit von makeQuery() und runQuery() in die gleiche reaktive Funktion verschoben und das hat den Trick gemacht. – David

+0

Wie sieht es aus, wenn Sie einen zuvor gespeicherten reaktiven Wert speichern müssen, z. B. rv $ myResultDataFrame ?? – aloplop85

Verwandte Themen