[英]isolate conditionalPanel in shiny
I've got a shiny
tab where the user can select several parameters via selectInput
. 我有一个
shiny
标签,用户可以在其中通过selectInput
选择多个参数。 After the selection, the user clicks on an actionButton
and a bunch of calculations happen on the server side. 选择之后,用户单击一个
actionButton
,服务器端将进行大量计算。 Depending on both the results and the selections, one or several conditionalPanels
are supposed to be shown. 根据结果和选择,应该显示一个或几个
conditionalPanels
。 The problem is that once the user changes the selection, the displayed conditionalPanel
changes immediately. 问题在于,一旦用户更改了选择,显示的
conditionalPanel
就会立即更改。 However, I'd like the conditions only to be evaluated after the user has pushed the actionButton
again and the calculations on the server side have been updated. 但是,我希望仅在用户再次按下
actionButton
并更新服务器端的计算之后才能评估条件。 Is there a way to tie the condition of the conditionalPanel
on an actionButton
? 有没有办法将conditionalPanel的
conditionalPanel
绑定到actionButton
?
Here is the best MWE I could come up with to capture all the nuances (actually, the dependency of the conditional panels on some server results is still missing here): 这是我能想到的最好的MWE,可以捕获所有细微差别(实际上,这里仍然缺少条件面板对某些服务器结果的依赖性):
library(shiny)
library(plyr)
ui <- fluidPage(
selectInput("variable", "Variable:",
c("SLength" = "Sepal.Length",
"SWidth" = "Sepal.Width",
"PLength" = "Petal.Length",
"PWidth" = "Petal.Width",
"Species" = "Species"),
multiple = TRUE),
br(),
actionButton("goButton", "Go!"),
hr(),
conditionalPanel(condition = "input['variable'].length == 1",
plotOutput("oneplot")),
conditionalPanel(condition = "input['variable'].length == 2",
plotOutput("twoplot"))
)
server <- function(input, output){
v <- reactiveValues(plot.type = NULL)
observeEvent(input$goButton, {
if (is.null(input$variable)) return(NULL)
if ("Species" %in% input$variable & length(input$variable > 1)){
sec.var <- input$variable[which(input$variable != "Species")]
v$summary <- ldply(by(iris[,sec.var], iris$Species, mean))
v$summary[,1] <- as.factor(v$summary[,1])
} else if ("Species" %in% input$variable)
v$summary <- table(iris$Species) else
v$summary <- iris[,input$variable]
})
output$oneplot <- renderPlot({
if (is.null(v$summary)) return(NULL)
if (input$variable == "Species") return(NULL)
hist(v$summary)
})
output$twoplot <- renderPlot({
if (is.null(v$summary)) return(NULL)
plot(v$summary)
})
}
shinyApp(ui, server)
So let's say I start the app and select SLength
and SWidth
, click the Go
-Button and get a dotplot. 假设我启动了该应用程序,然后选择
SLength
和SWidth
,单击Go
-Button并得到一个点图。 Then I'd want to show SLength
vs. PLength
, so I delete SWidth
from the selection field and the same moment I get two histograms, one for each of the previous selections. 然后,我想显示
SLength
vs. PLength
,所以我从选择字段中删除了SWidth
,同时获得了两个直方图,每个先前的选择一个。 The conditional panel immediately reacts to the change of input$variable
, while the observer within the server script is still waiting for me to push the button. 条件面板会立即对
input$variable
的更改作出反应,而服务器脚本中的观察者仍在等待我按下按钮。 Obviously, that's not the behaviour the user would expect. 显然,这不是用户期望的行为。 The expected behaviour would be that the evaluation of the conditions of the conditional panels only happens upon pushing the
Go
-button. 预期的行为是对条件面板条件的评估仅在按下“
Go
按钮时进行。 Is there a way to achieve this? 有没有办法做到这一点?
How about doing condition on server side? 在服务器端做条件怎么样?
library(shiny)
library(plyr)
ui <- fluidPage(
selectInput("variable", "Variable:",
c("SLength" = "Sepal.Length",
"SWidth" = "Sepal.Width",
"PLength" = "Petal.Length",
"PWidth" = "Petal.Width",
"Species" = "Species"),
multiple = TRUE),
br(),
actionButton("goButton", "Go!"),
hr(),
plotOutput("oneplot")
# conditionalPanel(condition = "input['variable'].length == 1",
# plotOutput("oneplot")),
# conditionalPanel(condition = "input['variable'].length == 2",
# plotOutput("twoplot"))
)
server <- function(input, output){
v <- reactiveValues(plot.type = NULL)
observeEvent(input$goButton, {
if (is.null(input$variable)) return(NULL)
if ("Species" %in% input$variable & length(input$variable > 1)){
sec.var <- input$variable[which(input$variable != "Species")]
v$summary <- ldply(by(iris[,sec.var], iris$Species, mean))
v$summary[,1] <- as.factor(v$summary[,1])
} else if ("Species" %in% input$variable)
v$summary <- table(iris$Species) else
v$summary <- iris[,input$variable]
})
output$oneplot <- renderPlot({
#Added actionButton dependency here
input$goButton
isolate({
if(length(input$variable)== 1) {
if (is.null(v$summary)) return(NULL)
if (input$variable == "Species") return(NULL)
hist(v$summary)
}
else {
if (is.null(v$summary)) return(NULL)
plot(v$summary)
}
})
})
#output$twoplot <- renderPlot({
#if (is.null(v$summary)) return(NULL)
#plot(v$summary)
#})
}
shinyApp(ui, server)
EDIT: Added another option by using submitButton 编辑:通过使用submitButton添加了另一个选项
You can also use submitButton()
and attach observeEvent()
to input$variable()
. 您还可以使用
submitButton()
,并将observeEvent()
附加到input$variable()
。 "Forms that include a submit button do not automatically update their outputs when inputs change, rather they wait until the user explicitly clicks the submit button." “包含输入按钮的表单不会在输入发生更改时自动更新其输出,而是会等到用户显式单击提交按钮之后。” submitButton
提交按钮
library(shiny)
library(plyr)
ui <- fluidPage(
selectInput("variable", "Variable:",
c("SLength" = "Sepal.Length",
"SWidth" = "Sepal.Width",
"PLength" = "Petal.Length",
"PWidth" = "Petal.Width",
"Species" = "Species"),
multiple = TRUE),
br(),
submitButton("Go!"),
hr(),
conditionalPanel(condition = "input['variable'].length == 1",
plotOutput("oneplot")),
conditionalPanel(condition = "input['variable'].length == 2",
plotOutput("twoplot"))
)
server <- function(input, output){
v <- reactiveValues(plot.type = NULL)
observeEvent(input$variable, {
if (is.null(input$variable)) return(NULL)
if ("Species" %in% input$variable & length(input$variable > 1)){
sec.var <- input$variable[which(input$variable != "Species")]
v$summary <- ldply(by(iris[,sec.var], iris$Species, mean))
v$summary[,1] <- as.factor(v$summary[,1])
} else if ("Species" %in% input$variable)
v$summary <- table(iris$Species) else
v$summary <- iris[,input$variable]
})
output$oneplot <- renderPlot({
if (is.null(v$summary)) return(NULL)
if (input$variable == "Species") return(NULL)
hist(v$summary)
})
output$twoplot <- renderPlot({
if (is.null(v$summary)) return(NULL)
plot(v$summary)
})
}
shinyApp(ui, server)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.