R 上传数据后停止计算,直到再次单击运行
我的shinyapp有问题。我想上传计算数据。当我这样做时,应用程序会在上传完成时自动运行整个脚本,因此我实现了一个操作按钮。当我启动应用程序并上传数据时,我必须点击操作按钮,程序就会执行,一切正常。但是,当我启动应用程序并首先单击“操作”按钮,然后上载数据时,程序将执行,而无需再次单击“运行”按钮。我在这里举了个例子。因为我的实际应用程序要大得多,所以我需要这个功能,即当我一开始上传的数据点击操作按钮后,程序在上传新数据后不会自动执行。我知道有R 上传数据后停止计算,直到再次单击运行,r,shiny,R,Shiny,我的shinyapp有问题。我想上传计算数据。当我这样做时,应用程序会在上传完成时自动运行整个脚本,因此我实现了一个操作按钮。当我启动应用程序并上传数据时,我必须点击操作按钮,程序就会执行,一切正常。但是,当我启动应用程序并首先单击“操作”按钮,然后上载数据时,程序将执行,而无需再次单击“运行”按钮。我在这里举了个例子。因为我的实际应用程序要大得多,所以我需要这个功能,即当我一开始上传的数据点击操作按钮后,程序在上传新数据后不会自动执行。我知道有isolate(),我尝试在每一个可能的位置实现它
isolate()
,我尝试在每一个可能的位置实现它,但没有任何结果。有人能帮我吗?
这是代码。使用示例数据
Mydata<-data.frame(A=1:1100,B=rnorm(1100, 50, 5))
write.csv(Mydata, file = "MyData.csv")
Mydata一种非常快速有效的方法是,在上传文件之前,使UI的该部分不可用。基本上,使用uiOutput()
调用来代替actionButton()
调用,并将actionButton()
移动到服务器中的renderUI()
函数中,该函数有条件地查找mapz()
的非空返回值。除非mapz()
的返回值为非空,否则无法按下该按钮。您还应将创建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不知道确切原因,但这似乎有效:
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)
ui这太棒了,非常感谢!但在render ui中,打开应用程序时不存在run按钮,在这种情况下没有问题,但可能在更大的实现中。没有办法使用像隔离这样的东西吗?我从来没有像你想的那样使用过隔离()。我处理可能被多次单击但仅在满足依赖项时执行操作的按钮的方法是设置一个被动buttonstate变量,并使用该变量控制按钮导致操作的能力。我将在答案中添加代码和注释。尽管你的答案中的函数将在上传文件后执行,并且只等待在按下操作按钮之前显示结果?!但我也希望只有再次按下操作按钮时才能执行,因为我的应用程序需要很多时间。那么还有别的办法吗?
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)