我有一个简单的示例Siny代码可以正常工作(下面)。它生成一个包含几个微小数据帧的列表(server.R中的反应对象'myout')。数据帧的数量基于用户的输入。('NumRuns')。 我当前的代码允许用户下载第一个数据帧 - 通过ui.R中的downloadButton和server.r中的downloadHandler。 我想知道是否有可能围绕downloadButton和downloadHandler创建一个循环,以便 - 在运行分析(actionButton)之后 - 用户获得尽可能多的按钮来下载,因为在'myout'中生成了数据帧。它甚至可能吗?
或者也许可以创建一个downloadButton,允许用户“选择”他/她想要下载的数据框? 非常感谢任何提示 - 因为我不确定如何处理它!
我的代码(我使用:runApp(launch.browser = T)
运行它)### My ui.R code:
shinyUI(pageWithSidebar(
headerPanel("My App"),
sidebarPanel(
numericInput('NumRuns','Number of runs',value=3,min=3,max=10,step=1),
br(),
actionButton(inputId="goButton","Run!"),
br(),
br(),
textInput("downloadData","Save My Data Frame:",value="Data Frame 1"),
downloadButton('downloadData','Save my file!')
),
mainPanel(
tabsetPanel(
tabPanel("Shows the 1st data frame",tableOutput("mydf"))
)
)
))
### My 'server.R' code:
shinyServer(function(input,output){
### Creating files for displaying and downloading
myout = reactive({
if(input$goButton==0) return(NULL)
nrruns=input$NumRuns
mylist=NULL
for(i in 1:nrruns){
mylist[[i]]<-data.frame(a=rnorm(10),b=runif(10))
names(mylist)[i]<-paste("dataframe",i,sep="")
}
return(mylist)
})
# Grabbing only the 1st data frame:
output$mydf <- renderTable({
if(input$goButton==0) return(NULL)
myout()$dataframe1
})
# Allowing to download only the 1st data frame:
output$downloadData <- downloadHandler(
filename = function() { paste(input$downloadData, " ",Sys.Date(),".csv",sep="") },
content = function(file) {
write.csv(myout()$dataframe1,file,row.names=F)
}
)
})
答案 0 :(得分:1)
这篇文章可能会给你答案。
https://groups.google.com/forum/#!msg/shiny-discuss/qGN3jeCbFRY/xOW5qoVrr94J
是的,这是可能的。您需要使用uiOutput / renderUI来渲染按钮,每个按钮具有不同的ID(例如downloadData1到downloadDataN)。要动态定义下载处理程序,请使用如下模式:
observe({
lapply(1:N, function(i) {
output[[paste0("downloadData", i)]] <- downloadHandler(...)
})
})
如果您的输出名称是动态的,那么您可以分配给输出[[id]]这一点很重要。