0

I am creating a shiny app and part of its purpose is to allow the user to upload a CSV and be able to select column/variables of interest. So far, I have successfully managed to upload a file, but the reactive part to select columns does not work, that is when I click on 'incorporate external information' nothing happens. I used this answer for guidance. How can I allow the user to select the columns and then display them accordingly? The purpose of column selection is to then allow the user to perform regression analysis on selected columns.

ui = navbarPage(tabPanel("Initial Exploration",
                dataTableOutput('mytable'),
                sidebarLayout(sidebarPanel(fileInput("file1", "Please choose a CSV file",
                                                     multiple = T,
                                                     accept = c("text/csv",
                                                                "text/comma-separated-values,text/plain",
                                                                ".csv")),
                                           tags$hr(),
                                           checkboxInput("header", "Header", TRUE),
                                           radioButtons("sep", "Separator",
                                                        choices = c(Comma = ",",
                                                                    Semicolon = ";",
                                                                    Tab = "\t"),
                                                        selected = ","),
                                           radioButtons("quote", "Quote",
                                                        choices = c(None = "",
                                                                    "Double Quote" = '"',
                                                                    "Single Quote" = "'"),
                                                        selected = '"'),
                                           tags$hr(),
                                           radioButtons("disp", "Display",
                                                        choices = c(Head = "head",
                                                                    All = "all"),
                                                        selected = "head")
                                           
                ),
                mainPanel(
                tableOutput("contents")),),
                actionButton("choice", "incorporate external information"),
                selectInput("columns", "Please Select Columns", choices = NULL, multiple = T),
                #tableOutput("Table_selected.col")
    ))

Server

# Tell the server how to assemble inputs into outputs
server = function(input, output, session) {
    output$contents = renderTable({
        
        # input$file1 will be NULL initially. After the user selects
        # and uploads a file, head of that data file by default,
        # or all rows if selected, will be shown.
        
        req(input$file1)
        
        df = read.csv(input$file1$datapath,
                       header = input$header,
                       sep = input$sep,
                       quote = input$quote)
        
        if(input$disp == "head") {
            return(head(df))
        }
        else {
            return(df)
        }
        
    })
    
    # Code for allowing the user to select the variables/columns of interest 
    info = eventReactive(input$choice, {
        inFile = input$file1
        # Instead # if (is.null(inFile)) ... use "req"
        req(inFile)
        
        # Changes in read.table 
        f = read.table(inFile$datapath, header = input$header, sep = input$sep, quote = input$quote)
        #df.1 = df
        vars = names(f)
        # Update select input immediately after clicking on the action button. 
        updateSelectInput(session, "columns","Please Select Columns", choices = vars)
        
        f
    })
    
    output$Table_selected.col = renderTable({
        f = info()
        f = subset(f, select = input$columns) #subsetting takes place here
        head(f)
    })

enter image description here

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Ed_Gravy
  • 1,841
  • 2
  • 11
  • 34
  • Generally, it is not recommended to put `updateSelectInput` inside a `eventreactive()`. It might be better to put it in a `observe`r. In your case, you need to click on `incorporate external information` button to see the choices of the selected data file. – YBS Apr 25 '21 at 02:36
  • When I replace eventReactive with observe, I get Error : Can't access reactive value 'file1' outside of reactive consumer. i Do you need to wrap inside reactive() or observer()? And with the original code, when I click on Incorporate external information, noting happens. – Ed_Gravy Apr 25 '21 at 03:59

1 Answers1

1

It may be better to process your data once, and then use it for additional purpose. Try this

ui = navbarPage(tabPanel("Initial Exploration",
                         dataTableOutput('mytable'),
                         sidebarLayout(sidebarPanel(fileInput("file1", "Please choose a CSV file",
                                                              multiple = T,
                                                              accept = c("text/csv",
                                                                         "text/comma-separated-values,text/plain",
                                                                         ".csv")),
                                                    tags$hr(),
                                                    checkboxInput("header", "Header", TRUE),
                                                    radioButtons("sep", "Separator",
                                                                 choices = c(Comma = ",",
                                                                             Semicolon = ";",
                                                                             Tab = "\t"),
                                                                 selected = ","),
                                                    radioButtons("quote", "Quote",
                                                                 choices = c(None = "",
                                                                             "Double Quote" = '"',
                                                                             "Single Quote" = "'"),
                                                                 selected = '"'),
                                                    tags$hr(),
                                                    radioButtons("disp", "Display",
                                                                 choices = c(Head = "head",
                                                                             All = "all"),
                                                                 selected = "head")
                                                    
                         ),
                         mainPanel(
                           tableOutput("contents")),),
                         actionButton("choice", "incorporate external information"),
                         selectInput("columns", "Please Select Columns", choices = NULL, multiple = T),
                         tableOutput("Table_selected.col")
))

# Tell the server how to assemble inputs into outputs
server = function(input, output, session) {
  
  mydf <- reactive({
    # input$file1 will be NULL initially. After the user selects
    # and uploads a file, head of that data file by default,
    # or all rows if selected, will be shown.
    
    req(input$file1)
    
    df = read.csv(input$file1$datapath,
                  header = input$header,
                  sep = input$sep,
                  quote = input$quote)
    
    if(input$disp == "head") {
      return(head(df))
    }
    else {
      return(df)
    }
    
  })
  
  output$contents = renderTable({
    req(mydf())
    mydf()
  })
  
  # Code for allowing the user to select the variables/columns of interest 
  info <- eventReactive(input$choice, {
    # inFile = input$file1
    # # Instead # if (is.null(inFile)) ... use "req"
    # req(inFile)
    # 
    # # Changes in read.table
    # f = read.table(inFile$datapath, header = input$header, sep = input$sep, quote = input$quote)
    # #df.1 = df
    # vars = names(f)
    # # Update select input immediately after clicking on the action button.
    # updateSelectInput(session, "columns","Please Select Columns", choices = vars)
    # 
    # f
    req(mydf())
    f <- mydf()
    f
  })
  
  observeEvent(input$choice, {  ## to update only when you click on the actionButton
  #observe({
    req(mydf())
    updateSelectInput(session, "columns","Please Select Columns", choices = names(mydf()))
  })
  
  
  output$Table_selected.col <- renderTable({
    input$choice
    req(info(),input$columns)
    f = info()
    f = subset(f, select = input$columns) #subsetting takes place here
    head(f)
  })
}

shinyApp(ui, server)
YBS
  • 19,324
  • 2
  • 9
  • 27
  • I can select the columns now, but these selected columns are not getting displayed as an updated table output. – Ed_Gravy Apr 25 '21 at 21:06
  • 1
    I am not sure I understand fully on how you want the actionButton to work. Please clarify in your question what is your expectation when you click on the actionButton. For now, you need to click on the action button to display the selected columns via input$columns. – YBS Apr 25 '21 at 21:28
  • Can you please also look at this question https://stackoverflow.com/questions/67259158/allowing-user-to-perform-regression-analysis-based-on-select-variables-in-shiny. I used your answer to get to the next step and thus posted a new question. – Ed_Gravy Apr 25 '21 at 23:28