R-Shiny中的自动多文件下载

时间:2013-12-31 19:05:42

标签: r bioinformatics shiny

我正在试图弄清楚如何让data.frame为子集本身,然后为每个子集写一个.csv文件。我正在编写一个shiny应用程序,它将为不同的工具生成模板文件,我需要能够为每个批次/板块/任何内容获取文件。显然,我们可以进行手动排序,但这种目的会失败。

在示例中,假设我有一个data.frame,其中4列名为1)PlateID,2)SampleName,3)Well和4)注释我希望通过PlateID进行子集,这样每个单独的板都会有它是自己的文件。

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

所以我想添加一些功能,我不知道如何处理它们。首先,我希望能够更好地控制数据的写入位置。我希望它与我的输入文件进入相同的文件,但我不知道如何强制这个?我尝试过这样的事情:

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

但在inFile$datapath中似乎是生成的临时文件夹/文件,而不是原始文件的直接链接!

另外,我想写一些像downloadHandler这样的东西,因为有一个按钮可以在点击时下载文件,但我不认为我可以在这种情况下使用它因为我正在写多个文件。如果我错了,请告诉我,因为这会让生活更轻松。我想我将使用actionButton和一个计数器变量,以便计数器是按钮+ 1的值,直到按钮被激活,在这种情况下它们是相等的,直到函数结束。显然我会有一个条件来处理其余的,但这是微不足道的,所以让我们专注于文件子集并下载!

谢谢!

2 个答案:

答案 0 :(得分:3)

zip()对我不起作用,但使用tar函数很容易..

      output$downloadData <- downloadHandler(
         filename = function() { paste("filesintar", '.tar', sep='') },
         content = function(file) {
           tar(file,"./dirwheremyfilesare") #  no inlcuye rutas hasta raíz.
         }
       )
希望这会有所帮助。 我尝试使用zip代替tar,但我遇到了错误:

        zip(file, paste("./dirwheremyfilesare/",dir("./dirwheremyfilesare"),sep=""))

谢谢你。

Antonio M。

答案 1 :(得分:1)

我修改了@amaurandi答案以完成OP问题,添加了一些我发现为我工作的额外装饰。警告,我还使用了plyr函数dlply来简化一下。

我用zip抛出错误(无法解释)来重现问题,但tar可以正常工作。原则上,这些是R中与平台无关的功能,但这也意味着您的安装正确设置了所有内容。

来自@amaurandi的OP起点和上一个答案片段的示例

output$multiDownload <- downloadHandler(
  filename = function(){
    # Time-stamp tar filename
    paste0("platetables-", gsub("\\D", "_", Sys.time()), ".tar")
  },
  content = function(file){
    # Loads the data. Could be reactive.
    tempData <- templateData()
    if(is.null(tempData)){
      # Protect against empty data.
      return(NULL)
    }
    plateNames = unique(tempData$PlateID)
    tempdir = tempdir()
    dlist = plyr::dlply(tempData, "PlateID", function(x) x[, c("names", "well", "comments")])
    for(i in plateNames){
      write.csv(x = dlist[[i]], file = paste0(tempdir, "/", i, ".csv"), row.names = FALSE)
    }
    tar(tarfile = file, files = tempdir)
  }
)