我正在试图弄清楚如何让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的值,直到按钮被激活,在这种情况下它们是相等的,直到函数结束。显然我会有一个条件来处理其余的,但这是微不足道的,所以让我们专注于文件子集并下载!
谢谢!
答案 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)
}
)