5
votes

I have a shiny app that selects xlsx/csv file and uploads it to the system and after uploading, I wish to populate the column names of the data table that I have extracted to a selectInput() or selectizeInput().

The below code represents an event of user uploading the data file

ui.R

    library(markdown)
    require(XLConnect)


    shinyUI(navbarPage(img(class="img-polaroid",
       src=paste0("http://www.iconsdb.com/icons/preview/black/stackoverflow-5-xl.png")),

       tabPanel("Table",
          titlePanel("Select Data"),
          sidebarLayout(
             sidebarPanel(
                selectInput("fileType", "Select File Type:",
                   c("MS Excel Worksheet (xls,xlsx)" = "xls",
                      "Text/CSV (.csv)" = "csv"
                      )
                   ),
                fileInput('file1', 'Choose file to upload',
                   accept = c(
                      'text/csv',
                      'text/comma-separated-values',
                      'text/tab-separated-values',
                      'text/plain',
                      '.csv',
                      '.tsv',
                      'application/vnd.ms-excel',
                      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                      '.xlsx',
                      '.xls'
                   )
                ),
                tags$hr(),
                checkboxInput('header', 'Header', TRUE),
                radioButtons('sep', 'Separator',
                   c(Comma=',',
                      Semicolon=';',
                      Tab='\t'),
                   ','),
                radioButtons('quote', 'Quote',
                   c(None='',
                      'Double Quote'='"',
                      'Single Quote'="'"),
                   '"'),
                tags$hr()


             ),
             mainPanel(
                dataTableOutput('table')
             )
          )

       ),
       tabPanel("Plot",
          sidebarLayout(
             sidebarPanel(
                radioButtons("plotType", "Plot type",
                   c("Scatter"="p", "Line"="l")
                )
             ),
             mainPanel(
                plotOutput("plot")
             )
          )
       ),
       navbarMenu("More",
          tabPanel("Summary",
             verbatimTextOutput("summary") 
          )
       )
    ))

server.R

shinyServer(
   function(input, output, session) 
      {
      output$plot <- renderPlot({
         plot(data$Count,data$Sales, type=input$plotType)
      })

      output$summary <- renderPrint({
         summary(data)
      })

      output$table <- renderDataTable({
         inFile <- input$file1

         if (is.null(inFile))
            return(NULL)
         if(input$fileType=='csv'){
            table1<-read.csv(inFile$datapath, header = input$header,
               sep = input$sep, quote = input$quote)
            return(table1)
         } else if(input$fileType=='xls'){
            table1 <- readWorksheetFromFile(inFile$datapath, sheet=1)
         }

      })
   }
)

Fair enough, I have now a working system of inputs that can take a data from Excel source or a text/CSV. Thereafter, I wish to create a dynamic list which would pass the values of colnames(output$table) to my ui.R and put it in the designated spot.

How do I do it?


I have tried using uiOutput() from Mason DeCamillis's answer to How to get vector of options from server.R to ui.R for selectInput in Shiny R App but R is throwing me a "Object not found" error.

Also, it occurred to me that I must use reactive() to be able to pass data to and fro to UI and server. But no clue, how do I do it.

1
This article is a useful reference for anybody trying to understand the answer by @NicE below, or generally get started with reactive UIs in Shiny.alistaire

1 Answers

8
votes

You can store the uploaded table in a data variable in your server.R and use the code from the link you posted to fill the selectInput.

In your server.R, you could do:

data <- reactive({
    inFile <- input$file1   
    if (is.null(inFile))
      return(NULL)
    if(input$fileType=='csv'){
      table1<-read.csv(inFile$datapath, header = input$header,
                       sep = input$sep, quote = input$quote)
      return(table1)
    } else if(input$fileType=='xls'){
      table1 <- readWorksheetFromFile(inFile$datapath, sheet=1)
    }
  })

    output$table <- renderDataTable({
     data()      
    })

    output$selector <- renderUI({
      selectInput("var", "Choose name:", as.list(colnames(data()))) 
    })

and in your ui.R, add uiOutput("selector") where you want the list to be.