上传数据后停止计算,直到再次点击运行

Posted

技术标签:

【中文标题】上传数据后停止计算,直到再次点击运行【英文标题】:stop calculation after upload of data until run is clicked again 【发布时间】:2017-09-04 22:04:42 【问题描述】:

我的闪亮应用有问题。我想为我的计算上传数据。当我这样做时,应用程序会在上传完成时自动运行整个脚本,所以我实现了一个操作按钮。当我启动应用程序并上传数据时,我必须单击操作按钮,程序执行并且一切正常。但是当我启动应用程序并先单击操作按钮然后上传数据时,程序会执行而无需再次单击运行按钮。我在这里做了一个例子。因为我的实际应用程序要大得多,所以我需要这个功能,即在为我首先上传的数据单击操作按钮后,程序不会在上传新数据后自动执行。我知道有isolate(),我试图在每个可能的位置实现它,但没有任何结果。有人可以帮我吗? 这里是代码。带有示例数据。

Mydata<-data.frame(A=1:1100,B=rnorm(1100, 50, 5))
write.csv(Mydata, file = "MyData.csv")

和应用程序:

ui <- fluidPage(
  titlePanel("Uploading Files"),
  sidebarLayout(
    sidebarPanel(
      fileInput('files1', 'Choose CSV File',
                accept=c('text/csv', 
                         'text/comma-separated-values,text/plain', 
                         '.csv'), multiple = TRUE),
      tags$hr(),

      radioButtons('sep', 'Separator',
                   c(Comma=',',
                     Semicolon=';',
                     Tab='\t'),
                   ','),
      actionButton("go","run",class = "btn-primary"),br()
    ),
    mainPanel(tags$head(tags$style(type="text/css", "
             #loadmessage 
                           position: fixed;
                           top: 95%;
                           left: 0px;
                           width: 100%;
                           padding: 5px 0px 5px 0px;
                           text-align: center;
                           font-weight: bold;
                           font-size: 100%;
                           color: #000000;
                           background-color: #CCFF66;
                           z-index: 105;
                           
                           ")),
              conditionalPanel(condition="$('html').hasClass('shiny-busy')",
                               tags$div("Loading...",id="loadmessage")),
      verbatimTextOutput('text1')

      )
      )
  )


server <- function(input, output) 

observeEvent(input$go,
  mapz <- reactive(
    inFiles <- input$files1

    if (is.null(inFiles))
      return(NULL)
    Q <- read.csv(input$files1[[1, 'datapath']],sep=input$sep,dec="." )
    names(Q)<-c("A","B")
    Q<-Q[Q$A<1000,]
    nom<-seq(round(min(Q$A)),floor(max(Q$A)),by=1)
    counts<-matrix(NA,nrow=length(nom),ncol=length(input$files1[,1]))
    return(list(as.matrix(nom),counts))
  )
  output$text1 <-renderPrint(if(is.null(input$files1)==FALSE) as.data.frame(mapz()[[1]]))
)

shinyApp(ui, server)

非常感谢!

【问题讨论】:

【参考方案1】:

您可以执行此操作的一种非常快速且有效的方法是,在上传文件或文件之前,使 UI 的该部分不可用。基本上进行uiOutput() 调用代替actionButton() 调用并将actionButton() 移动到服务器中的renderUI() 函数中,该函数有条件地寻找mapz() 的非NULL 返回。除非mapz() 没有返回非NULL,否则无法按下该按钮。您还应该将创建mapz() 的反应式移动到observeEvent() 之外,以便无论是否按下按钮,它都对应用程序可用。现在作为警告,这永远不会重置按钮,只要上传了文件,按钮就可以按下。它在功能上是相同的,所以!运算符的工作方式类似于 ==FALSE 条件。以下是建议更改的代码:

 ui <- fluidPage(
 titlePanel("Uploading Files"),
 sidebarLayout(
 sidebarPanel(
  fileInput('files1', 'Choose CSV File',
            accept=c('text/csv', 
                     'text/comma-separated-values,text/plain', 
                     '.csv'), multiple = TRUE),
  tags$hr(),

  radioButtons('sep', 'Separator',
               c(Comma=',',
                 Semicolon=';',
                 Tab='\t'),
               ','),
  uiOutput("runbutton"),br()
),
mainPanel(tags$head(tags$style(type="text/css", "
         #loadmessage 
                       position: fixed;
                       top: 95%;
                       left: 0px;
                       width: 100%;
                       padding: 5px 0px 5px 0px;
                       text-align: center;
                       font-weight: bold;
                       font-size: 100%;
                       color: #000000;
                       background-color: #CCFF66;
                       z-index: 105;
                       
                       ")),
          conditionalPanel(condition="$('html').hasClass('shiny-busy')",
                           tags$div("Loading...",id="loadmessage")),
  verbatimTextOutput('text1')

  )
  )
)


server <- function(input, output) 
output$runbutton <- renderUI(
    if(!is.null(mapz())
    actionButton("go","run",class = "btn-primary")
    
)
mapz <- reactive(
inFiles <- input$files1

if (is.null(inFiles))
  return(NULL)
Q <- read.csv(input$files1[[1, 'datapath']],sep=input$sep,dec="." )
names(Q)<-c("A","B")
Q<-Q[Q$A<1000,]
nom<-seq(round(min(Q$A)),floor(max(Q$A)),by=1)
counts<-matrix(NA,nrow=length(nom),ncol=length(input$files1[,1]))
return(list(as.matrix(nom),counts))
)
observeEvent(input$go,

output$text1 <-renderPrint(if(is.null(mapz())==FALSE)  as.data.frame(mapz()[[1]]))
)

shinyApp(ui, server)

【讨论】:

非常感谢!但是使用渲染 ui 打开应用程序时,运行按钮不存在,在这种情况下没有问题,但可能在更大的实现中。有没有办法像隔离一样使用某物? 我从来没有像你想的那样使用isolate()。我处理可能多次单击但仅在满足依赖项时才执行操作的按钮的方法是设置一个反应性按钮状态变量并使用它来控制按钮引起操作的能力。我将使用 cmets 将代码添加到答案中。 尽管您的答案中的函数将在文件上传后执行,并且只等到按下操作按钮才显示结果?!但我也希望仅在再次按下操作按钮时执行,因为我的应用程序需要很多时间。那么可能还有其他方法吗?【参考方案2】:

不知道具体原因,但这似乎有效:

ui <- fluidPage(
  titlePanel("Uploading Files"),
  sidebarLayout(
    sidebarPanel(
      fileInput('files1', 'Choose CSV File',
                accept=c('text/csv', 
                         'text/comma-separated-values,text/plain', 
                         '.csv'), multiple = TRUE),
      tags$hr(),

      radioButtons('sep', 'Separator',
                   c(Comma=',',
                     Semicolon=';',
                     Tab='\t'),
                   ','),
      actionButton("go","run",class = "btn-primary"),br()
    ),
    mainPanel(tags$head(tags$style(type="text/css", "
                                   #loadmessage 
                                   position: fixed;
                                   top: 95%;
                                   left: 0px;
                                   width: 100%;
                                   padding: 5px 0px 5px 0px;
                                   text-align: center;
                                   font-weight: bold;
                                   font-size: 100%;
                                   color: #000000;
                                   background-color: #CCFF66;
                                   z-index: 105;
                                   
                                   ")),
              conditionalPanel(condition="$('html').hasClass('shiny-busy')",
                               tags$div("Loading...",id="loadmessage")),
              verbatimTextOutput('text1')

    )
    )
    )


server <- function(input, output) 

  observeEvent(input$go,
    mapz1 <- reactive(
      inFiles <- input$files1

      if (is.null(inFiles))
        return(NULL)
      Q <- read.csv(input$files1[[1, 'datapath']],sep=input$sep,dec="." )
      names(Q)<-c("A","B")
      Q<-Q[Q$A<1000,]
      nom<-seq(round(min(Q$A)),floor(max(Q$A)),by=1)
      counts<-matrix(NA,nrow=length(nom),ncol=length(input$files1[,1]))
      return(list(as.matrix(nom),counts))
    )
    mapz<-reactive(isolate(mapz1()))

    output$text1 <-renderPrint(as.data.frame(mapz()[[1]]))
  )

shinyApp(ui, server)

【讨论】:

以上是关于上传数据后停止计算,直到再次点击运行的主要内容,如果未能解决你的问题,请参考以下文章

jquery怎么打开本地图片预览,点击确定后上传

XHR 中止不会停止文件上传

记录python上传文件的坑

使用xcode 8上传后,应用不会显示在活动标签中

struts2+jquery如何实现点击“上传”按钮,实现从本机选择图片,然后自动上传,类似于上传证件的那种

C# winform中timer函数如何停止,点运行后可再次启动周期事件