ZT_Geo
ZT_Geo

Reputation: 413

Reactively select column name from a table after reactively selecting that table from a list

I have a shiny application which imports multiple csv/txt files as a list and then outputs the selected table reactively. I would like to be able to reactively select multiple columns within this dataset to ratio to one another but I am having trouble reactively reading the column names of the selected table. A shortened version of my code looks like this.

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

# create dummy CSVs -------------------------------------------------------
DF1 <- data.frame(x = 1:3, y = 2:4)
DF2 <- data.frame(x = 4:6, y = 5:7)
DF3 <- data.frame(x = 7:9, y = 8:10)
DF4 <- data.frame(x = 10:12, y = 11:13)

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
    ),

   selectizeInput("num1", "Numerator (1)", 
                   choices = NULL, 
                   selected = NULL, 
                   multiple = FALSE
                   
    ),
    
    
    selectizeInput("den1", "Denominator (1)", 
                   choices = NULL, 
                   selected = NULL, 
                   multiple = FALSE
    ),
  ),
  mainPanel(DTOutput("table"),
            DTOutput("filtered_table"))
))

server <- function(input, output, session) {
  observeEvent(input$files, {
    freezeReactiveValue(input, "selected_table")
    updateSelectizeInput(session,
                         inputId = "selected_table",
                         choices = input$files$name,
                         server = TRUE)
  })

observeEvent(input$files, {
    freezeReactiveValue(input, "num1")
    updateSelectizeInput(session,
                         inputId = "num1",
                         choices = names(input$files$name),
                         server = TRUE)
    
  })

observeEvent(input$files, {
    freezeReactiveValue(input, "den1")
    updateSelectizeInput(session,
                         inputId = "den1",
                         choices = names(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)

How can I reactively read the column names and assign them as inputs for the Numerator and Denominator selectizeInput() functions? I appreciate any and all advice!

Upvotes: 1

Views: 118

Answers (1)

Meisam
Meisam

Reputation: 631

Why are you using the name attribute of your input file to access its data? Printing its content doesn't bring anything, try yourself:

# In the ui add:
textOutput("testOutput")

# In the server add:
output$testOutput <- renderText(names(input$files$name))

You should use datapath column which you have already read into your table_list() reactive element. Now check if you can retrieve the column names:

# Make a reactive element for the colnames:
colnameReactive <- reactive({
    req(table_list(), input$selected_table)
    dfTmp <- table_list()[[input$selected_table]]
    colnames(dfTmp)
  })

# Now replace testOutput with this:
output$testOutput <- renderText(colnameReactive())

So then you just need to choose the contents of this new reactive element into your updateSelectizeInput(). Hope it helps!

EDIT As the OP pointed out we should observe this new reactive as well:

observeEvent(colnameReactive(), {freezeReactiveValue(input, "num1") updateSelectizeInput(session, inputId = "num1", choices = colnameReactive(), server = TRUE)})

Upvotes: 1

Related Questions