0

I created a Shiny App, which accepts Excel and csv files as input. It furthermore, should forecast a metric which can be found in the uploaded file. To be able to define the right column in the file, the user should be able to select the column which should be forecasted. This is why I want to have a select input area, where all column names of the file are displayed. But I don't find the right solution.

In the following my app so far:

ui:

 ui <- fluidPage(  

  #definition which file input is allowed
  fileInput(
    'file',
     label = h4("Welche Datei soll hochgeladen werden?"),
     multiple= FALSE,
     accept = c(
      'text/csv',
      'text/comma-separated-values,text/plain',
      '.csv',
      '.xlsx'
   )
  ),

server:

server <- function(input, output) {

#read data 
data <- reactive({

  validate(need(input$file, ""))
  infile <- input$file

  if (input$type == "1") {
   read.csv(infile$datapath,
           header = input$header,
           sep = input$sep,
           stringsAsFactors = FALSE)
  } else {
  read_xlsx(infile$datapath)
  }    

})

And I thought about something like this in server, but could not finally solve the problem:

names <- reactive({
 df <- data()
 if (is.null(df)) return(NULL)

 items=names(df)
 names(items)=items

 return(names(items))

})

Thanks for any help!

jogo
  • 12,469
  • 11
  • 37
  • 42
nississippi
  • 327
  • 2
  • 17

2 Answers2

3

Inside UI, you should add:

selectInput("columnid","Column to forecast",choices=c())

your server should start like this: server <- function(session,input, output) {

and inside the server, after the else inside your reactive you can add:

updateSelectInput(session,"columnid",choices=colnames(mydata))

remember to call "mydata" the data that was read, and to return it, like this:

data <- reactive({

  validate(need(input$file, ""))
  infile <- input$file

  if (input$type == "1") {
   mydata=read.csv(infile$datapath,
           header = input$header,
           sep = input$sep,
           stringsAsFactors = FALSE)
  } else {
   mydata=read_xlsx(infile$datapath)
  }
  updateSelectInput(session,"columnid",choices=colnames(mydata))
return(mydata)
})
  • Thank you for the quick answer. What do you mean with your last sentence? Where and how do I call mydata? – nississippi Jan 08 '19 at 15:15
  • I have got one more question. I just realized that now the app indeed gives me the drop down possibilites as desired. However, when I try to switch to the second or third entry, it always goes back to the first one. So I am not really able to switch to another entry. Do you know what is wrong here? – nississippi Jan 09 '19 at 15:26
  • This means that your updateSelectInput is being called everytime you try to select a column. You need to put it inside a code block that runs only when the file is read. I'm guessing you are calling data() inside some observeEvent or eventReactive that is causing updateSelectInput to be reavaluated over and over. – Ricardo Fernandes Campos Jan 09 '19 at 15:32
0

You can also use observe in server. observe does not return anything. Unlike reactive, it responds immediately (and not lazily). It's best used for ip/op operations.

ui <- fluidPage (
 selectInput("select_input_id", "INPUT COLUMNS", choices = c())
)



server <- function(input, output) {

  #read data 
  data <- reactive({

    infile <- input$file

    if (input$type == "1") {
     df <- read.csv(infile$datapath,
             header = input$header,
             sep = input$sep,
             stringsAsFactors = FALSE)

     return (df)
    }
  })

observe({
  updateSelectInput(
    session,
    "select_input_id",
    choices = names(data())
  )
)}
}
theairbend3r
  • 679
  • 9
  • 26