在R Shiny中无需上传文件生成文件路径列表用于批量处理
Solution: Get Local File/Folder Paths for Processing Without Uploading
I get exactly what you're trying to do—you want to replicate your existing R script's loop logic in Shiny, where you either pick a folder (to process all files inside) or select specific files, without having to upload those large files (which is unnecessary and slow). Here's a straightforward implementation using the shinyFiles package that matches your workflow:
Step 1: Full Working Code
library(shiny) library(shinyFiles) ui <- fluidPage( # Buttons for folder and file selection shinyDirButton("select_folder", "Choose Folder (Process All Files Inside)", "Pick a folder"), shinyFilesButton("select_files", "Choose Specific Files", "Pick one or more files", multiple = TRUE), # Display selected paths h4("Selected Paths:"), verbatimTextOutput("display_paths"), # Optional: Button to trigger processing actionButton("run_processing", "Start Processing"), verbatimTextOutput("processing_log") ) server <- function(input, output, session) { # Set up accessible volumes (adjust if needed) volumes <- getVolumes() # Reactive variable to store our target file paths selected_paths <- reactiveVal(NULL) # Handle folder selection observeEvent(input$select_folder, { shinyDirChoose(input, "select_folder", roots = volumes, session = session) if (!is.null(input$select_folder)) { # Parse the selected folder path folder_path <- parseDirPath(volumes, input$select_folder) # Get ALL full file paths in this folder (matches your original list.files call) file_list <- list.files(folder_path, full.names = TRUE) # Update our reactive path list selected_paths(file_list) } }) # Handle file selection observeEvent(input$select_files, { shinyFileChoose(input, "select_files", roots = volumes, session = session) if (!is.null(input$select_files)) { # Parse selected file paths (datapath is the local full path) file_df <- parseFilePaths(volumes, input$select_files) # Extract the full paths into a list file_list <- as.character(file_df$datapath) # Update our reactive path list selected_paths(file_list) } }) # Display the selected paths output$display_paths <- renderPrint({ if (!is.null(selected_paths())) { selected_paths() } else { "No files/folder selected yet" } }) # Handle processing when button is clicked observeEvent(input$run_processing, { req(selected_paths()) # Initialize log log_text <- c("Processing started...") # Loop through each path (exactly like your original script!) for (path in selected_paths()) { # Replace this with YOUR function call # Example: obj <- path; your_custom_function(obj) log_text <- c(log_text, paste("Processing:", path)) # Add your actual processing logic here # ... } # Update log output output$processing_log <- renderPrint({ cat(paste(log_text, collapse = "\n")) }) }) } shinyApp(ui = ui, server = server)
Key Details Explained
- No Uploads Needed: All we're doing is grabbing the local file/folder paths directly—no file upload occurs, which solves your large file problem.
- Matches Your Original Logic:
- When you select a folder, we use
list.files(folder_path, full.names = TRUE)—this is exactly the same as your originallistBands <- list.files(myInputDir1, full.names = T)line. - The
selected_paths()reactive variable holds the list of full paths, which you can loop through just like you did in your script.
- When you select a folder, we use
- Flexible Selection: Users can choose either a folder (process all files) or specific files, which covers both use cases you mentioned.
How to Integrate Your Custom Function
Replace the example loop code in observeEvent(input$run_processing, ...) with your actual processing logic. For example:
# Inside the loop your_custom_function(path) # path is the full file path, just like your original 'obj'
This approach keeps your existing R script logic intact while wrapping it in a Shiny interface that's intuitive for users.
内容的提问来源于stack exchange,提问作者dtanon
相关产品推荐
相关产品推荐

