Shiny tableOutput for list elements from multiple .txt files

Viewed 48

I have multiple text files that I imported into shiny as a list.

#ui
library(shiny)

fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Choose File",
                multiple = TRUE,
                accept = c("text/csv",
                           "text/comma-separated-values,text/plain",
                           ".dp_txt", ".is_txt")),
    ),
    
    mainPanel(
      
      tableOutput("files"),
    )
  )
)

#server

function(input, output, session){
  
  output$files <- renderTable({
    
    req(input$file1)
    
    library(readr)
    
    files <- lapply(input$file1$datapath, function(x) read_csv(x))
    files
  })
}

I want to be able to select the different elements of this list and display them as tables. How can I individually output each table within my list in shiny (i.e., let the user select which table they want to display)? Every element (table) within the list will have a name. Can I use somehow use selectInput() to call each table within the list according to that tables name? Thanks in advance!

1 Answers

Please check the following:

The file input is observed for changes and updates the choices of the selectizeInput.

Once the files are uploaded the choices are populated and a table is displayed according to the selection.

library(DT)
library(shiny)
library(data.table)

# create dummy CSVs -------------------------------------------------------
DF1 <- data.frame(x = 1:3, y = letters[1:3])
DF2 <- data.frame(x = 4:6, y = letters[4:6])
DF3 <- data.frame(x = 7:9, y = letters[7:9])
DF4 <- data.frame(x = 10:12, y = letters[10:12])

mapply(
  write.csv,
  x = list(DF1, DF2, DF3, DF4),
  file = list("DF1.csv", "DF2.csv", "DF3.csv", "DF4.csv"),
  row.names = FALSE
)

# shiny app ---------------------------------------------------------------
ui <- fluidPage(sidebarLayout(
  sidebarPanel(
    fileInput(
      "files",
      "Choose File",
      multiple = TRUE,
      accept = c(
        "text/csv",
        "text/comma-separated-values,text/plain",
        ".dp_txt",
        ".is_txt"
      )
    ),
    selectizeInput(
      inputId = "selected_table",
      label = "Table Selection",
      choices = NULL,
      selected = NULL,
      multiple = FALSE
    )
  ),
  mainPanel(DTOutput("table"))
))

server <- function(input, output, session) {
  observeEvent(input$files, {
    freezeReactiveValue(input, "selected_table")
    updateSelectizeInput(session,
                         inputId = "selected_table",
                         choices = input$files$name,
                         server = TRUE)
  })
  
  table_list <- reactive({
    req(input$files)
    setNames(lapply(input$files$datapath, function(x) {
      fread(x)
    }),
    input$files$name)
  })
  
  output$table <- renderDT({
    req(table_list(), input$selected_table)
    table_list()[[input$selected_table]]
  }, server = FALSE)
}

shinyApp(ui, server)

PS: feel free to replace DTOutput with tableOutput if preferred.

Related