14

Beginner to R and shiny here! Tried to make a minimal working example... I want to check a condition on a reactive input value. What am I doing wrong?

library(shiny)

ui<-fluidPage(

  numericInput(inputId="a", label=NULL, value=0),
  textOutput(outputId="out")
)

server <- function(input, output) {
  x <- reactive(input$a)
  if (x() < 4) 
    {y<-1}
  else
  {y<-0}

  output$out <- renderText({y})
}

shinyApp(ui = ui, server = server)

The error message:

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.)

6
  • As the message says, you can only use x() within a reactive context (for example, inside observe, local, render.... functions). Also you y value must be defined outside the function and in the same level or upper level of where it is used. Commented Jun 8, 2016 at 18:47
  • @warmoverflow : So there is no way to check a condition on a reactive value? Sorry super new to R Commented Jun 8, 2016 at 18:50
  • You can but must be inside one of those context. For example you can check it right inside renderText Commented Jun 8, 2016 at 18:51
  • BTW input$a is already reactive by itself so you don't need to enclose it with reactive and assign to a new variable. Commented Jun 8, 2016 at 18:52
  • @warmoverflow : I see. That's unfortunate. This was a minimal working example for trying to do a large amount of computation outside of renderOutputs, because my real code is (1) much longer, and (2) has multiple outputs based on y, and recomputing it inside each renderOutput is really slow. Thank you Commented Jun 8, 2016 at 18:55

3 Answers 3

12

You just need to use reactive with your if so that shiny knows that y changes when x does.

library(shiny)

ui<-fluidPage(

  numericInput(inputId="a", label=NULL, value=0),
  textOutput(outputId="out")
)

server <- function(input, output) {
  x <- reactive(input$a)
  y <- reactive( if (x()<4) 1 else 0 )

  output$out <- renderText({ y() })
}

shinyApp(ui = ui, server = server)
Sign up to request clarification or add additional context in comments.

1 Comment

Ah wow great! Assigning the entire IF statement to a variable is not intuitive to me, but you were right.
8

The answer above from John Paul is certainly acceptable, but I thought you might like to see another way as a part of your learning process. I will let StackOverflow sort out which is more advisable.

library(shiny)

ui<-fluidPage(

  numericInput(inputId="a", label=NULL, value=0),
  textOutput(outputId="out")
)

server <- function(input, output) {
  state <- reactiveValues()

  observe({
    state$x <- input$a
    state$y <- ifelse(state$x < 4, 1, 0)
  })

  output$out <- renderText({ state$y })
}

shinyApp(ui = ui, server = server)

3 Comments

Do you know if there is a reason why using the reactiveValues would be preferable here? I get the impression that the RStudio folks like this better but I don't fully understand what the advantage might be.
I watched the videos from the conference, and I adopted the approach, but unfortunately don't know why. I'm about to really dig into the shiny internals, so maybe then I will figure it out. In terms of a big complicated project, I think the reactiveValues approach simplifies some of the code. I am hoping others on StackOverflow will enlighten us.
@timelyportfolio Oh I like this! I'll have to play around with reactiveValues() and Observe() but it seems much easier, not having to keep track of which values are reactive, and making sure all downstream variables are assigned with reactive()
4

here's my attempt. 1) as stated, you don't need to wrap input$a in reactive context and save as x. just use input$a 2) you don't need reactiveValues in this simple example. just save y as a reactive variable. then, in the renderText, access by calling the function ("y()")

library(shiny)

ui<-fluidPage(

  numericInput(inputId="a", label=NULL, value=0),
  textOutput(outputId="out")
)

server <- function(input, output) {

  y <- reactive({
    if (input$a < 4) {
      return(1)
    } else {
      return(0)
    }
  }
  )

  output$out <- renderText({y()})
}

shinyApp(ui = ui, server = server)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.