2016-01-15 12 views
5

Sto scrivendo un'app lucida in cui l'output dovrebbe dipendere dal valore di una variabile che viene calcolata in un'espressione reattiva in lucido. Invece di riprodurre l'applicazione effettiva credo di aver ricreato il mio problema con il seguente semplice applicazione:Utilizzo di un'espressione reattiva in un'istruzione if in lucido

ui.R file: 

    library(shiny) 

    shinyUI(pageWithSidebar(

    headerPanel("Illustrating problem"), 

    sidebarPanel(

    numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step  =5) 

), 

    mainPanel(

    h4('You entered'), 

    verbatimTextOutput("oid1"), 

    verbatimTextOutput("odic") 

) 
)) 

server.R file 


library(shiny) 

shinyServer(

    function(input, output) { 

    output$oid1 <- renderPrint({input$id1}) 

    x<-reactive({5*input$id1}) 

    if (x()>50) output$oid2<-renderPrint({"You entered a number greater than 10"}) 

    else output$oid2<-renderPrint({"You entered a number less than or equal to 
10"}) 

    } 
) 

Se l'eseguo come questo allora ottengo l'errore: Errore in.getReactiveEnvironment()$currentContext(): `

Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)

Se cambio l'istruzione if a: if (x>50) ... tanto sono l'errore:

Error in x > 50 : comparison (6) is possible only for atomic and list types

Quando cambio l'istruzione if a: if (reactive({(x>50)})) ... tanto sono il messaggio di errore:

Error in if (reactive({ : argument is not interpretable as logical

Apprezzerei molto di aiuto

risposta

3

Nota che le opere Shiny basano secondo un modello event-driven - come praticamente tutte le interfacce utente orientate alla grafica (e oggi è la stragrande maggioranza). Non è un concetto nuovo, è stato in circolazione almeno dagli anni '80, ma è più complicato di una programmazione che segue un singolo diagramma di flusso - ci vuole un po 'di tempo per abituarsi.

In ogni caso, in Shiny reactive e output e observe le dichiarazioni devono essere al livello più alto, non credo che ci siano eccezioni a questo.

probabilmente si desidera qualcosa di simile:

library(shiny) 

u <- shinyUI(pageWithSidebar(

    headerPanel("Illustrating problem"), 

    sidebarPanel(
    numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step =5) 
), 

    mainPanel(

    h4('You entered'), 
    verbatimTextOutput("oid1"), 
    verbatimTextOutput("oid2") 

) 
)) 

s <- shinyServer(function(input, output) { 

    output$oid1 <- renderPrint({input$id1}) 

    x<-reactive({5*input$id1}) 

    output$oid2<-renderPrint({ 
     if (x()>50){ 
     "You entered a number greater than 10" 
     } else { 
     "You entered a number less than or equal to 10" 
     } 
    } 
) 
} 
) 
shinyApp(ui = u, server = s) 

Cedendo:

enter image description here

+0

Si ottiene un punto di troppo, per lo sforzo di screenshot ... BTW non credo che è incoraggiato, ma puoi certamente mettere le dichiarazioni di output all'interno di un osservatore/reattivo. Ma non dovrebbe –

+0

Grazie per le tue spiegazioni. Il mio problema è che nella mia app effettiva ho un sacco di comandi all'interno delle istruzioni if ​​else e non è un singolo comando renderPrint. Qualche idea su come farlo? – MSR

+0

Vedere le mie modifiche sopra. –

8

un paio di problemi. Il primo e più grande problema è che non sembri capire come funziona la reattività. L'errore indica "operazione non consentita senza un contesto reattivo attivo" e questo è il problema: si accede a x() all'interno del corpo principale della funzione server ma non in un contesto reattivo. Qualsiasi funzione render* è un contesto reattivo, ad esempio. Quindi per risolvere questo è semplice spostare l'istruzione if all'interno dello renderPrint.

L'altro piccolo problema è che gli ID di output non corrispondono (verbatimTextOutput("odic") vs output$oid2).

Se non si capisce la reattività, consiglio vivamente di impiegare mezz'ora per capirlo meglio. This tutorial ha una sezione sulla reattività che può essere utile, oppure puoi rileggere il tutorial lucido ufficiale di RStudio.

Ecco il codice per la vostra applicazione fisso (ho tolto un po 'di elementi dell'interfaccia utente inutili)

library(shiny) 
ui <- fluidPage(
    numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step=5), 
    verbatimTextOutput("oid1"), 
    verbatimTextOutput("oid2") 

) 
server <- function(input, output, session) { 
    output$oid1 <- renderPrint({input$id1}) 

    x<-reactive({5*input$id1}) 

    output$oid2<-renderPrint({ 
    if (x()>50) { 
     "You entered a number greater than 10" 
    } else { 
     "You entered a number less than or equal to 10" 
    } 
    }) 
} 
shinyApp(ui = ui, server = server) 
+0

Oh bene, pensavo che nessuno lo stesse guardando. Un punto per te comunque :) –