0

I want to write an app that reads in the uploaded data, then puts enough numericInput due to the number of unique elements in a column (the name of the columns is Big). This question here helped me.

The code is as below:

library(shiny)
 ui <- fluidPage(
  fileInput(inputId = "up","", accept = '.csv'),
  uiOutput("sliders")
)

server <- function(input, output, session) {

  INPUT <- reactive({
    infile <- input$up

    #validate(need(input$up, "Input a valid filepath."))      

    read.csv(infile$datapath, header = TRUE, sep = ",")
  })

 inVars <- reactive({
    unique(INPUT()$Big)
  })

  output$sliders <- renderUI({
    pvars <- length(inVars())
    lapply(seq(pvars), function(i) {
      numericInput(inputId = paste0("range", pvars[i]),label = pvars[i],value = 1)
    })
  })

}

shinyApp(ui = ui, server = server)

Three questions:

1. When I put

if (is.null(infile))
return(NULL)

instead of validate, it gives me an error which looks like this:

missing value where TRUE/FALSE needed

What should I do to get rid of this error?

2. How could I add a label for each one of the numericInput?

3. How could I use the input values later? In a reactive environment?

Thanks

1 Answers1

1

The problem is not with the if (is.null(infile)) statement, it is with the lapply function. When the Shiny app just starts, the entire server function is executed, the length of inVars() is 0 and the sequence seq(pvars) will be 1 0. Then the numericInput will fail because you are making a reference to pvars[i] when i is equal to 0.

Below is the code that fixes the problem and also answers your questions.

library(shiny)
 ui <- fluidPage(
  fileInput(inputId = "up","", accept = '.csv'),
  uiOutput("sliders")
)

server <- function(input, output, session) {

  INPUT <- reactive({
    infile <- input$up
    if (is.null(infile))
      return(NULL)
    read.csv(infile$datapath, header = TRUE, sep = ",")
  })

 inVars <- reactive({
    unique(INPUT()$Big)
  })

  output$sliders <- renderUI({
    pvars <- length(inVars())
    if (pvars > 0) {
      div(
        lapply(seq(pvars), function(i) {
          numericInput(inputId = paste0("range", inVars()[i]),label = inVars()[i],value = 1)
        }),
        actionButton("getValues", "Get values"),
        tableOutput('table')
      )
    }
  })

  values <- 0

  # get the values of each numericInput and store them in "values"
  observeEvent(input$getValues, {
      # initialize vector 
      values <<- rep(NA, length(inVars()))
      names(values) <<- inVars()

      for(k in 1:length(inVars())) { 
        inputName <- paste0("range", inVars()[k])
        # only get a value if the numeric input exists
        if (!is.null(inputName))
          values[[k]] <<- input[[inputName]]
      }
    # show values as a table
    output$table <- renderTable(data.frame(
                        variable = inVars(),
                        values))

  })

}

shinyApp(ui = ui, server = server)

Update:

To test the code, use a .csv file with content like:

num,Big
1,a
2,a
3,b
4,b
5,c
6,c
7,d
8,d

Screenshot:

Screenshot

Geovany
  • 5,389
  • 21
  • 37
  • This does not work. I added `dataTableOutput("table")` in `ui` but still not working. Also, I want to automatically read the values without and action button. – Kaveh akbari Jul 24 '17 at 19:48
  • It should work with `tableOutput`, I updated the answer with the input data used to test and a screenshot, please check you have the last version of Shiny. If you want to automatically read the values you can review the solution in https://stackoverflow.com/a/40643541/4322318 – Geovany Jul 24 '17 at 20:34
  • There is one problem with your code that I can't figure it out. If you change the value of `d`, the value of `c` will change. When I ran your code for the first time with different dataset, an error came up: `arguments imply differing number of rows: 4, 5`. It seems something is wrong inside the `observeEvent`. – Kaveh akbari Jul 25 '17 at 22:39
  • I'm unable to reproduce the error you mention of changing the value of `d` by changing `c`. Related to the second problem, the code was just as an example for a very specific input data, it seems that the problem is because it is expecting a dataset with a column named `Big`. – Geovany Jul 26 '17 at 17:56
  • In the `numericInput`, change the value for `C`, and press the get values. Although you change the value of `C` the value of `D` changes. – Kaveh akbari Jul 27 '17 at 17:40
  • I found the issue and edited in your response. It kept saving in the wrong place. – Kaveh akbari Jul 28 '17 at 21:51