I have a problem with my shinyapp. I want to upload data for my calculations. When I do so the app automatically runs through the whole script the moment the upload is complete, so I implemented an action button. When I start the app and upload the data I have to click on the action button, the program executes and everything works fine. But when I start the app and click on the action Button first and then upload data, the program executes without having to click on the run button again. I made an example here. Because my actual app is ways bigger I need this feature that the programs is not executing automatically after uploading new data once the action button was clicked for the data I uploaded in the first place. I know that there is isolate()
and I tried to implement it in every position possible but without any result. Can somebody help me out here?
Here the code. with example data.
Mydata<-data.frame(A=1:1100,B=rnorm(1100, 50, 5))
write.csv(Mydata, file = "MyData.csv")
and the app:
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)
Many thanks!
答案 0 :(得分:1)
一种非常快速有效的方法是在上传文件或文件之前使UI的那部分不可用。基本上调用uiOutput()
来代替actionButton()
调用,并将actionButton()
移动到服务器中的renderUI()
函数中,该函数具有条件查找{{}的非NULL返回值1}}。除非mapz()
有非NULL返回,否则按钮不可用。您还应该在mapz()
之外移动创建mapz()
的反应,以便无论是否按下该按钮,它都可以对应用程序使用。现在作为一个警告,这永远不会重置按钮,只要有上传的文件按钮是可按下的。它在功能上是一样的!运算符的工作方式类似于== FALSE条件。下面是建议更改的代码:
observeEvent()
答案 1 :(得分:0)
不知道原因究竟是什么,但这似乎有效:
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)