Automatic multi-file download in R-Shiny

Viewed 3310

I'm trying to figure out how to get a data.frame to subset itself and then write a .csv file for each subset. I'm writing a shiny app which will generate template files for different instruments, and I need to be able to get a file for each batch/plate/whatever. Obviously, we could do a manual sort, but that kind of defeats the purpose.

In example, say that I have a data.frame with 4 columns named 1) PlateID, 2) SampleName, 3) Well and 4) Comments and I want to subset by the PlateID such that each individual plate will have it's own file.

output$multiDownload <- renderText({
#templateData() just loads the data, nothing special;
#If you wanna see it let me know, but I think it's bulky
  tempData <- templateData()
  if(is.null(tempData)){return(NULL)}

    #If there are more than one plate, subset by plate ID and write each file
    if(max(tempData$PlateID) > 1){
    for(i in 1:max(tempData$PlateID)){
        tempSubsetForWrite <- subset(tempData, tempData$PlateID == i, select =   c("names", "well", "comments"))
        write.csv(tempSubsetForWrite, file = paste0("file ", i, " of ", max(tempData$PlateID), row.names = FALSE)
      }
  } else {
    write.csv(tempData, file = "file", row.names = FALSE)
  }
}) 

So I want to add a few features and I'm not sure how to approach them. First, I would like to have better control of where the data is written. I would like it to go into the same file as my input files, but I'm not sure how to force this? I tried doing something like:

inFile <- input$templateGenerationFile
write.csv(tempData, paste0(inFile$datapath, "/file ", i, " of ", max(tempData$PlateID))

but in inFile$datapath appears to be a temp folder/file which is generated and not a direct link to the original file!

Also, I'm wanting to write something that will act like a downloadHandler in the sense of having a button which will download the files upon clicking, but I don't think I can use that in this scenario because I am writing multiple files. If I'm wrong then PLEASE let me know, as that would make life easier. I am thinking that I will use an actionButton and a counter variable so that the counter is the value of the button + 1 until the button is activated, in which case they are equal until the end of the function. Obviously I would have a conditional which handles the rest, but that is trivial so lets focus on the file subset and download!

Thanks!

2 Answers
Related