R shiny app won't render plots until all multiple tabs was clicked

I built a simple R shiny app with multiple tabs. When I run the app, the plot on each tab would not show when I first clicked on each of the tabs. An error message shows attempt to select less than one element in get1index. However, after I clicked on each of the tabs until the last tab, plots started to show up on each tab without error message. Following is the screenshot I have when I run the app. Would you please kindly point out which direction I should pursue to solve this issue? Thanks,

Before I clicked on each of the tabs, I got the following ERROR message with no plot rendered.
image

After I clicked on each of the tabs, starting from the last tab I clicked, all plots start to show up.

The simplified UI and server part is similar to the following.

ui <- fluidPage(
  titlePanel("EMR Comparative Analysis"),
  tabsetPanel(
    tabPanel("Overall Comparison",
             sidebarLayout(
               sidebarPanel(
                 # Radio button to select between EMR Site and EMR Form
                 radioButtons(
                   inputId = "overall_comparison_type",
                   label = "Select comparison type:",
                   choices = c("EMR Site" = "emrsite", "EMR Form" = "emrform"),
                   selected = "emrsite"
                 ),
                 # Dropdown menu for study selection
                 uiOutput("overallStudySelectInput"),
                 # Input selection for cumulative daily time series
                 uiOutput("overallMetricSelectInput")
               ),
               mainPanel(
                 plotOutput("overallPlot")
               )
             )
    ),
}

# Server ----
server <- function(input, output, session) {
....
# Consolidate reactive expressions for data selection
  selectedData <- reactive({
    print("Running selectedData() reactive...")
    
    list(
      cumulative = {
        # req(input$cumulative_comparison_type, input$select_cumulative_study, input$select_cumulative_metric)
        print("Fetching cumulative data...")
        data_list <- get(input$cumulative_comparison_type)
        study_data <- data_list[[input$select_cumulative_study]]
        print(paste("Selected study for cumulative TS:", input$select_cumulative_study))
        kpi_data <- study_data[[input$select_cumulative_metric]]
      },
      monthly = {
        # req(input$select_monthly_study, input$select_monthly_metric)
        print("Fetching monthly data...")
        data_list <- get(input$monthly_comparison_type)
        study_data <- data_list[[input$select_monthly_study]]
        print(paste("Selected study for monthly TS:", input$select_monthly_study))
        kpi_data <- study_data[[input$select_monthly_metric]]
      },
      overall = {
        # req(input$select_overall_study, input$select_overall_metric)
        print("Fetching overall data...")
        data_list <- get(input$overall_comparison_type)
        study_data <- data_list[[input$select_overall_study]]
        print(paste("Selected study for overall TS:", input$select_overall_study))
        kpi_data <- study_data[[input$select_overall_metric]]
      }
    )
  })
  # Render overall Plot
  output$overallPlot <- renderPlot({
    data <- selectedData()$overall
    
    print("overall data structure:")
    print(str(data))
    
    comparison_var <- if (input$overall_comparison_type == "emrsite") {
      "is_emr_site"
    } else {
      "is_emr_form"
    }
    
    comparison_label <- c(
      "Yes" = if (input$overall_comparison_type == "emrsite") "EMR Sites" else "EMR Forms",
      "No" = if (input$overall_comparison_type == "emrsite") "Non-EMR Sites" else "Non-EMR Forms"
    )
    
    data[[comparison_var]] <- factor(data[[comparison_var]], levels = names(comparison_label), labels = comparison_label)
    
    # Identify columns starting with 'ratio' or 'duration_median'
    plot_var <- grep("^ratio|^duration_median", names(data), value = TRUE)
    
    ggplot(data, aes_string(x = comparison_var, y = plot_var, fill = comparison_var)) +
      geom_bar(stat = "identity", position = "dodge") +
      labs(title = "Overall Comparison by Study", x = "EMR vs. Non-EMR", y = "Overall Ratio/Median", fill = "Comparison Group") +
      theme_minimal()
  })
}

After I clicked on each of the tabs, starting from the last tab I clicked, all plots start to show up.

Hi Jane,

Without seeing a little more of the code it would be hard to pin this down. It seems like it might be a situation where a value might be assigned to a variable used in this code after something runs on the other tabs.

My main recommendation, especially if you are writing this code in RStudio, is to throw a browser() call at the start of the renderPlot contents (before data <- selectedData()$overall). When you run this code locally the program will pause once it hits the browser call and take you back to the console (lower left part of the RStudio window). You can then step through each line of code and see in the environmental variables (upper right part of the RStudio window) what values are being assigned to variables in the local, reactive environment. You should also be able to see which part of the renderPlot call is throwing that error.

@danomene Thanks a lot for your advice! Over the past two days, I slowly realized that the cause of the delay in rendering might be because that I wrapped the inputs of multiple tabs into one list as the output of reactive expression selectedData(). I unwrapped the list and got rid of selectedData(), then the delay of the rendering of plots on multiple tabs finally disappeared. I added the selectedData() reactive expression to my original post for reference. Now the only issue is the ERROR message ERROR: attempt to select less than one element in get1index. On StackOverflow, a member commented that this error might relate with this line

data[[comparison_var]] <- factor(data[[comparison_var]], levels = names(comparison_label), labels = comparison_label)

He / She suggested check the init phase when input$overall_comparison_type may be NULL . I am working toward this direction.

By the way, thank you for mentioning browser() to me! I did not have much success in using browser() for debugging so far. I used to use print() in R shiny app development.

For convenience to skip running code for which required inputs are NULL, shiny has provided the req() function; you seem to be aware of such as it appears in your code example (though commented out)

Thank you, @nirgrahamuk . req() does not help in this issue. I tried adding quite a few of the req(), then commenting them out. The error message still shows up for about half second. Then the plot will render. By the way, I have fixed part of the original issue. Initially, I have to click on all tabs until I reached the last tab for the plots to be rendered in each tab. I changed the selectedData() reactive expression and broke down the reactive expression to multiple reactive corresponding to each plot in each tab. It solved the delaying of rendering plots across tabs. However, the ERROR message of attempt to select less than one element in get1index still persists for the first time I clicked on each tab as a flash. After the initial rendering of the plots, the error message does not show up anymore when I make selections on the study level or KPI level.

I'm glad that browser() has been of some use - I primarily use it when writing Shiny apps and it has saved me loads of time hunting bugs. The other big bug-hunting trick is adding options(shiny.reactlog = TRUE) to the code before the server call. When you run the app you can hit Alt+F3 (iirc) and it will bring up a timeline for the app and show which reactive elements are being called and invalidated, etc. at each point in time. This could allow you to observe what variable had a state change the first time you opened the tab, versus later times. It also gives a visual indication on which variables are reactively tied to other variables in your code.

I have a feeling that it might be related to having the renderUI (that pair to your uiOutput) initializing the input$select_*_study and input$select_*_metric variables (which is what I am assuming is happening).