这是我关于stackoverflow的第一个问题,我已经使用R 3个月了。我有很多要学习的!任何帮助深表感谢。提前感谢您的时间。
我想要发生什么: 用户从下拉框中选择一个类别(动物或食物),然后单击下一次。适当的ui组件将呈现和显示。然后,只要Chooser Input组件的右侧框为空,就应禁用(灰显)Next按钮。只有当用户在右侧框中至少有一个选项时,才应启用“下一步”按钮,用户可以单击它。
问题:渲染选配器输入组件后,右侧框为空,但未禁用“下一步”。这是错误:
Warning in run(timeoutMs) :
Unhandled error in observer: argument is of length zero
observeEvent(input$widget2)
下面是一个演示ui.R和sever.R来重现我的问题。 (但是,我将把解决方案实现为更大,更复杂的GUI。)代码使用 shinyBS ,因此您首先需要安装包并加载库。该代码还使用 chooserInput ,它需要两个文件: chooser.R 和 www / chooser-binding.js 。有关更多信息,请参阅以下链接: http://shiny.rstudio.com/gallery/custom-input-control.html
### The following libraries need to be loaded BEFORE runApp()
### library(shiny)
### library(shinyBS)
source("chooser.R") # Used for Custom Input Control UI component (chooserInput)
# chooser.R is saved in the same location as the ui.R and server.R files
# chooserInput also requires chooser-binding JScript script file, which should be located within "www" folder
shinyUI(navbarPage("navbarPage Title",
tabPanel("tabPanel Title", titlePanel("titlePanel Title"),
fluidPage(
#### NEW ROW #####################################################################################################
fluidRow(wellPanel(
# Instructions for initial screen
conditionalPanel(condition = "input.ButtonNext == 0", tags$b("Step 1: Choose category and click 'Next'")),
# Instructions for 'Foods'
conditionalPanel(condition = "input.ButtonNext == 1 && input.widget1 == 'Foods'", tags$b("Step 2: Move Food(s) of interest to the right box and click 'Next'")),
# Instructions for 'Animals'
conditionalPanel(condition = "input.ButtonNext == 1 && input.widget1 == 'Animals'", tags$b("Step 2: Move Animals(s) of interest to the right box and click 'Next'"))
)),
#### NEW ROW #####################################################################################################
fluidRow(
# Drop down box for first selection
conditionalPanel(
condition = "input.ButtonNext == 0",
selectInput("widget1", label = "",
choices = c("Foods",
"Animals"))),
# This outputs the dynamic UI components based on first selection
uiOutput("ui1")
),
#### NEW ROW #####################################################################################################
fluidRow(tags$hr()), # Horizontal line separating input UI from "Next" button
#### NEW ROW #####################################################################################################
fluidRow(
column(1, offset=10,
# UI component for 'Next' button
conditionalPanel(condition = "input.ButtonNext < 2", bsButton("ButtonNext", "Next"))
),
column(1,
HTML("<a class='btn' href='/'>Restart</a>")
)
)
) # End of fluidPage
) # End of tabPanel
)) # End of navbarPage and ShinyUI
shinyServer(function(input, output, session) {
# Widget to display when number of clicks of "Next" button (ButtonNext) = 1
output$ui1 <- renderUI({
if(input$ButtonNext[1]==1) {
print("I am in renderUI") # Used to help debug
# Depending on the initial selection, generate a different UI component
switch(input$widget1,
"Foods" = chooserInput("widget2", "Available frobs", "Selected frobs", leftChoices=c("Apple", "Cheese", "Carrot"), rightChoices=c(), size = 5, multiple = TRUE),
"Animals" = chooserInput("widget2", "Available frobs", "Selected frobs", leftChoices=c("Lion", "Tiger", "Bear", "Wolverine"), rightChoices=c(), size = 5, multiple = TRUE)
)
}
}) # End of renderUI
# Disable "Next" button when right side of multi select input is empty
observeEvent(input$widget2, ({
widget2_right <- input$widget2[[2]]
print(widget2_right) # Used to help debug
if(widget2_right == character(0)) {
updateButton(session, "ButtonNext", disabled = TRUE)
} else {
updateButton(session, "ButtonNext", disabled = FALSE)
}
})) # End of observeEvent
}) # End of shinyServer
使用优先级和恢复/暂停提到的类似问题(下面的链接)但没有提供示例。如果这是我的问题的有效解决方案,请提供一些代码。
R shiny Observe running Before loading of UI and this causes Null parameters
EXTRA注意:提供的代码是一个小型演示,是从我为用户开发的更大的GUI中重新创建的,可以进行一系列选择,在每个选项之间单击“下一步”。根据他们在每个步骤中所做的选择,将从csv文件生成新选项。因此,呈现和显示的ui组件取决于用户点击“下一步”的次数以及他们之前做出的选择。最后,选择用于对大型数据集进行排序,以便用户只能绘制他们感兴趣的数据。双重条件是我使用conditionalPanel和actionButton的VALUE来呈现和显示当前ui组件的原因。用户需要。我的代码有效(除了上面的问题 - HA!)。但是,我已经读过使用actionButton的VALUE是不好的编码习惯。如果对另一种处理双重条件的方法有任何建议,请告诉我。
答案 0 :(得分:2)
在server.R中,我替换了
if(widget2_right == character(0))
与
if(length(widget2_right)==0)
现在该程序按照我的意愿运行。
当右框为空时,widget2_right = character(0)
。我了解到,将向量与character(0)
进行比较会产生logical(0)
,而不是TRUE
或FALSE
。但是,length(character(0)) = 0
。因此,只要右侧框中没有选择,if(length(widget2_right)==0)
将为TRUE
。