0

I am trying to write a script to upload a .csv file and to throw a subset option (in the shape of checkboxes) back in the UI. After uploading, previously invisible checkboxes are displayed, showing actual data values. At the same time, an action button also appears, to be clicked after (potential) alteration of the selected data values (via the checkboxes).

So what do I have?
1) Upload - OK.
2) Selection and display of checkboxes - OK.
3) Display of action button - OK.
4) Proper execution of the desired action (= subsetting the data) - not OK; subsetting returns an empty or NULL dataframe, apparently.

Any help would be greatly appreciated.

Here's the code.

I will add that the Dte field I am basing the subsetting on is a date field, which is originally in the csv as dd/mm/yyyy format and without quotes.

library(shiny)
library(lubridate)

ui = fluidPage(sidebarPanel(width = 2,
                            fileInput('files', '', accept = c('text/csv','text/comma-separated-values','text/tab-separated-values','text/plain','.csv','.tsv')),
                            checkboxInput('header', 'Header', TRUE),
                            radioButtons('sep', 'Separator', c(Comma=',',Semicolon=';',Tab='\t'), selected=';'),
                            radioButtons('quote', 'Quote', c(None='','Double Quote'='"','Single Quote'="'"), selected='"'),
                            uiOutput('apply')),
               mainPanel(width = 10, uiOutput('years'), dataTableOutput("tabel4")
               )
)

server = function(input, output, session) {
  ### if a csv is selected (through fileInput()), it is read
  vis0 <- eventReactive(input$files, {
    vis <- read.csv(input$files$datapath, header = input$header, sep = input$sep, quote = input$quote,
                           stringsAsFactors =FALSE)
    vis$Dte <- as.Date(as.character(vis$Dte), "%d/%m/%Y")
    vis$year <- factor(year(vis$Dte))
    vis
    })
  ### button appearing only after 
  output$apply <- renderUI({
    if (is.null(input$files)) return()
    actionButton("Load", "APPLY DATA")
    })
  ### get checkbox values from data and throw them back to UI
  output$years <- renderUI({
    df <- vis0()
    df$year <- as.character(df$year)
    if (is.null(df)) return(NULL)
    items= sort(unique(df$year))
    names(items)=items
    checkboxGroupInput("dependent","Check or uncheck years to be included or excluded",
                       choices=items, selected = items, inline = TRUE)
    })
  ### use selected checkbox values to reduce initial dataset
  vis1 <- reactive({
    if (is.null(input$Load)) return()
    if (input$Load==0) return()
    data <- vis0()
    data <- subset(data, as.character(year) %in% input$years)
    data
    })
  ### using the checkbox-reduced data to create a table  
  output$tabel4 <- renderDataTable({
    vis1()
    })
  }

shinyApp(ui = ui, server = server, options = list(launch.browser=TRUE))
  • Are you sure you are using `uiOutput` the right way? The [docs](https://shiny.rstudio.com/articles/dynamic-ui.html) say that *In ui.R, use a uiOutput to tell Shiny where these controls should be rendered.* That is to say, I don't quite know if `input$years` really returns sth for the server to work with. – patrick Jun 14 '17 at 03:13
  • I would say I did what you cited...? Also see this working example I followed (the top answer). https://www.google.be/url?sa=t&source=web&rct=j&url=https://stackoverflow.com/questions/27769186/shiny-show-buttons-only-after-file-has-been-uploaded&ved=0ahUKEwiejZ6XzrzUAhVGK1AKHWOyBzkQFggcMAA&usg=AFQjCNH1YpN-jPY2OEGwWlOBdxw6YxYIKA&sig2=BHJrx4mYZiiBF4VfiUZQxg – Jeroen Speybroeck Jun 14 '17 at 05:35
  • I tried to directly get input$years in the UI output as textual output. Seems you are right, or at least the selected years are not showing. Any ideas, alternatives, ...? – Jeroen Speybroeck Jun 14 '17 at 15:03
  • I always find it hard to read Shiny but shouldn't you be able to read in / assign to a variable the contents of `checkboxGroupInput("dependent"...`? e.g. `input$dependent`? If not, it would be helpful to have an exmpl dataset. – patrick Jun 14 '17 at 15:23
  • I will post an answer, because I figured it out myself :D – Jeroen Speybroeck Jun 14 '17 at 16:34

1 Answers1

0

I found the solution!

One silly error (at least) was that dependent had to be years. Maybe there were more (especially in the if checks) that I fixed and didn't track properly, but the below code works.

library(shiny)
library(lubridate)

ui = fluidPage(sidebarPanel(width = 2,
                            fileInput('files', '', accept = c('text/csv','text/comma-separated-values','text/tab-separated-values','text/plain','.csv','.tsv')),
                            checkboxInput('header', 'Header', TRUE),
                            radioButtons('sep', 'Separator', c(Comma=',',Semicolon=';',Tab='\t'), selected=';'),
                            radioButtons('quote', 'Quote', c(None='','Double Quote'='"','Single Quote'="'"), selected='"'),
                            uiOutput('apply')),
               mainPanel(width = 10, uiOutput('years'),tags$br(),tags$br(), 
                         textOutput('showyrs'),tags$br(),tags$br(),
                         textOutput('yrz'),tags$br(),tags$br(),
                         dataTableOutput("tabel4")
               )
)


######################################################################

server = function(input, output, session) {
  ### if a csv is selected (through fileInput()), it is read
  vis0 <- reactive({
    req(input$files)
    vis <- read.csv(input$files$datapath, header = input$header, sep = input$sep, quote = input$quote,
                           stringsAsFactors =FALSE)
    vis$Dte <- as.Date(as.character(vis$Dte), "%d/%m/%Y")
    vis$year <- factor(year(vis$Dte))
    vis
    })

  ### button appearing only after 
  output$apply <- renderUI({
    if (is.null(input$files)) return()
    actionButton("Load", "APPLY DATA")
    })

  ### get checkbox values from data and throw them back to UI
  output$years <- renderUI({
    req(vis0)
    df <- vis0()
    df$year <- as.character(df$year)
    if (is.null(df)) return(NULL)
    items= sort(unique(df$year))
    names(items)=items
    checkboxGroupInput("years","Check or uncheck years to be included or excluded",
                       choices=items, selected = items, inline = TRUE)
    })

  ### show input$years
  output$showyrs <- renderText({
    req(input$files)
    if (is.null(input$years)) {
      "Nothing..."
    } else if (input$years==0) {
      "Nothing..."
    } else {input$years}
  })

  ### use selected checkbox values to reduce initial dataset
  vis1 <- reactive({
    req(input$years)
    if (is.null(input$Load)) return()
    if (input$Load==0) return()
    data <- vis0()
    data <- subset(data, as.character(year) %in% input$years)
    data
    })

  ### using the checkbox-reduced data to create a table  
  output$tabel4 <- renderDataTable({
    vis1()
    })
  }

shinyApp(ui = ui, server = server, options = list(launch.browser=TRUE))