Select source data from directory members

I presently have a shiny app that allows me to navigate to ./data, select a .csv file of interest, and then perform necessary actions on the data in that file. When the user is finished, he/she can then select the next file and view output based upon those elements. A simplified version of the code is found below.

That said, I want to present the user with a list of category names linked to respective .csv files, from which they can select from a dropdown menu. Their menu selection would result in loading the associated .csv file, and render desired outcomes on screen. But, I am not finding a viable solution. How would I adapt the following code so that the user can select source data file from a single dropdown selection?

Thanks, Matt

library("DT")
library("data.table")
library("shiny")
githubinstall("shinytest")


ui <- fluidPage(

    sidebarPanel ( 

       fileInput("file1",
                label=HTML("<font size=3>Select File</font>"),
                multiple=FALSE,
                accept=c("text/csv",
                "text/comma-separated-values,text/plain",
                ".csv")),
 
  mainPanel(
    textOutput("text1"))))


server <- function(input,output) {

  output$text1 <- renderText({
    inFile <- input$file1
    if (is.null(inFile)){
      return(NULL)
    }
    file1=read.csv(inFile$datapath,header=TRUE, sep=",")
    
    paste(file1$gradyear)
  })
 }


shinyApp(ui, server)

How are the category names linked to the csvs? Is there a 1-to-1 linking between them (i.e., can a given category uniquely identify a csv)? Do you know these categories ahead of time? Or are they supposed to be dynamically generated from the csvs?

1 Like

The categories will be uniquely tied to the .csv file names, as the data sets will contain grouping variable names in their titles. My goal is to ingage code that explicitly points an edited/clean category name (e.g., Race/ethnicity) to a given file (e.g., raceeth.csv) to help the user better interpret the content that they are selecting and avoid having to search for the source data. Though comparing apples and oranges, I am thinking about this as being analogous to using a selectInput statement in which the edited/clean choices presented to users via dropdown are explicitly tied to unedited column names.

My knee-jerk reaction is that there are a lot of ways this can go wrong that are beyond your control (it would require very strong assumptions about your user's file system), would it be possible to host the data on your shiny server so that users don't have to upload data? Or is there no way around that?

At present, the intent is to host the data within the Shiny server, as it will be pre-aggregated for performance reasons. So, there will be very tight constraints on naming conventions and their alignment with the code. Permit me to add to the post...when you mention hosting on the Shiny server so folks don't have to upload, I'm not sure to what you refer. As I see it, users choose to see outcomes disaggregated by race, gender, income, etc. as defined by separate .csv files. They select the disaggregation, which would in turn load the data into the plotly chart and datatable. Is this in sync with what you're referencing?

Thank you for looking into this, by the way!

Ah, ok. If the files already reside on the server, you can avoid using fileInput() altogether (that is primarily for allowing users to upload files that reside on their file system). I would just do something like this:

library(shiny)

# load all the possible data sets
datasets <- list(
  `Race/Ethnicity` = read.csv("raceeth.csv"),
  `Age/Background` = read.csv("ageback.csv")
)

ui <- fluidPage(
  selectInput("data", "Pick a dataset" choices = names(datasets)),
  dataTableOutput("table")
)

server <- function(input, output, session) {
  output$table <- renderDataTable({
    req(input$data)
    datasets[[input$data]]
  })
}

shinyApp(ui, server)

If that app takes awhile to load, there are two things you might want to consider:

(1) Faster alternatives to read.csv(). Some good options are vroom::vroom(), data.table::fread(), and feather::read_feather().
(2) Consider putting the file reading/loading into a global.R script. The benefit is that once the data has been loaded for one user, then other users don't have to wait for that same data to be loaded.

1 Like

That is perfect. I will give that a whirl first thing in the morning. I will let you know how it turns out.
Thank you!

The dropdown menu is rendered as desired, and it correctly identifies whether the .csv files are present. However, though the code renders a table containing the entirety of the specified .csv file, I cannot determine how identify the imported .csv so as to create a dataframe on which I can subset/manipulate content. What am I missing? Thanks!

The final issue is resolved.

file1 <- data.frame(datasets[[input$data]])

builds a dataframe from the .csv, thus permitting the following test case:

        file1_sub <- file1[file1$state == 'Alabama' & file1$year == '2018',]
        datatable(file1_sub)

Thank you!
Matt

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.