zesla zesla -3 years ago 119
R Question

pass object generated in server back to ui in shiny

I need to create an object (or variable( in my server part and pass back into ui checkboxGroupInput. My file is a little complicated. Here I just use diamonds data to illustrate what I'm trying to do, although what the app is doing is meaningless. I created a df, a subset of diamonds dataset. I'm trying to pass it back to the ui checkboxGroupInput, so that I can select what columns to show. My question is how do I pass df back to ui? thanks in advance.

Here is my app.r:

library(shiny)
library(ggplot2)
library(DT)

ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("nrow", label = h3("number of rows"),
choices = list(5, 10, 20),
selected = 5),
checkboxGroupInput("show_vars", "Columns in diamonds to show:",
names(df), selected = names(df))
),
mainPanel(
DT::dataTableOutput("mytable1")
)
)
)


server <- function(input, output) {

# choose rows to display
df = diamonds[sample(nrow(diamonds), input$nrow), ]

output$mytable1 <- DT::renderDataTable({
DT::datatable(df[, input$show_vars, drop = FALSE])
})

}

shinyApp(ui, server)


Error message:

Warning: Error 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.)

Answer Source

The specific error you're seeing is because you're trying to use input$nrow outside of any reactive context (as per the error) in this line.

 df = diamonds[sample(nrow(diamonds), input$nrow), ]

So this needs to be move into some sort of reactive expression

Also, you can create the UI element inside the server using renderUI and uiOutput functions. That way it's easier to control the UI from the server.

library(shiny)
library(ggplot2)
library(DT)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("nrow", label = h3("number of rows"), 
                  choices = list(5, 10, 20), 
                  selected = 5),
      uiOutput(outputId = "show_vars")
    ),
    mainPanel(
      DT::dataTableOutput("mytable1")
    )
  )
)


server <- function(input, output) {

  # choose rows to display
  df <- reactive({
    diamonds[sample(nrow(diamonds), input$nrow), ]
  })

  output$show_vars <- renderUI({
    checkboxGroupInput("show_vars", "Columns in diamonds to show:",
                       names(df()), selected = names(df()))
  })


  output$mytable1 <- DT::renderDataTable({
    DT::datatable(diamonds[, input$show_vars, drop = FALSE])
  })

}

shinyApp(ui, server)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download