0

I have this simple Shiny app in which I want the user to choose among four dataframes -- namely df1, df2, df3 and df4 -- the one than will be displayed using DT:dataTableOutput. The problem is I get this error:

Error in dots_list(...) : object 'df_opt' not found

And I do not know why. I thought the error messages was firing because of something related to the input$df_opt argument I previously had in eventReactive, but then I removed it by adding a button input. Nevertheless, I keep getting the same error message

Does anyone understand why I'm getting this message?

This is a reproducible example of my app:

library(shiny)
library(DT)

 choices_df <- c("opt1", "opt2", "opt3", "opt4")

ui <- fluidPage(
        sidebarLayout(
            sidebarPanel(
                radioButtons(
                    inputId = df_opt,
                    label = "Choose a database",
                    choices = df_choices,
                    selected = choices_df[1] ),
                actionButton(
                  inputId = df_button,
                  label   = "")
                ),
                        mainPanel(
                        DT::dataTableOutput("base_p1")
                          )
            ))


server <- function(input, output) {

  df_selected <- eventReactive(
    input$df_button, { 

      if( input$df_opt == choices_df[1] ){
        df1
      }
      if( input$df_opt == choices_df[2] ){
        df2
      }
      if( input$df_opt == choices_df[3] ){
        df3
      }
      if( input$df_opt == choices_df[4] ){
        df4
      }

     })

  output$base_p1 <- DT::renderDataTable( df_selected(), filter = "top")
}

shinyApp(ui = ui, server = server)
2
  • Maybe replace your df_opt in quotes "df_opt" in inputId ? Commented Dec 19, 2019 at 12:02
  • Indeed! My mistake was so simple that I did not even consider it. Thank you very much! Commented Dec 19, 2019 at 17:27

1 Answer 1

1

Here is a working version of what you want to do, but with reactiveValues. So basically I find it better to create like an empty holder for reactive variable, then just assign the wanted df to it when user changes input. Code:

library(shiny)

library(DT)

df_choices <- c("opt1", "opt2", "opt3", "opt4")

df1 <- matrix(rnorm(100,10,10),10,10)
df2 <- matrix(rnorm(100,100,10),10,10)
df3 <- matrix(rnorm(100,1099,10),10,10)
df4 <- matrix(rnorm(100,100000,10),10,10)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      radioButtons(
        inputId = "df_opt",
        label = "Choose a database",
        choices = df_choices,
        selected = choices_df[1] ),
      actionButton(
        inputId = "df_button",
        label   = "click to show")
    ),
    mainPanel(
      DT::dataTableOutput("base_p1")
    )
  ))


server <- function(input, output) {

df <- reactiveValues(df=df1)

  observeEvent(input$df_button,{
    if( input$df_opt == choices_df[1] ){
      df$df <- df1
    }
    if( input$df_opt == choices_df[2] ){
      df$df <-df2
    }
    if( input$df_opt == choices_df[3] ){
      df$df <- df3
    }
    if( input$df_opt == choices_df[4] ){
      df$df <- df4
    }
  })

  output$base_p1 <- DT::renderDataTable( df$df, filter = "top")
}

shinyApp(ui = ui, server = server)

EDIT: And yes, inputID should be strings, so "df_opt" and "df_button".

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer! Do you prefer the reactiveValues way because you find it more straight or because of some performance consideration?
That depends on your code, if your event is expensive then it is better to calculate once and save it. I usually do operations on the reactive variable, so it is too expensive to calculate it every time. Please accept the answer by clicking on green tick below upvote buttons. :)

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.