eventReactive表达式中的反应对象问题

时间:2018-06-13 09:07:33

标签: shiny leaflet

我收到错误:“警告:我的Shiny App中的[.data.frame:undefined columns”中出错。为简单起见,我的可重现示例仅呈现表输出,但在实际使用中,我有一个传单映射对象,它始终使用所选列作为由renderTable生成的值参数。目标是通过用户输入构建过滤后的数据帧。

正如您所看到的,我正在使用renderUI对象,因为我需要在我的滑块小部件中使用灵活的范围。因此,我需要一个eventReactive对象,它最终将数据帧过滤为两列:'entity'和用户输入值列。

library(shiny)
library(tidyverse)


entity <- c('A', 'B', 'C', 'D', 'E')
ge <- data.frame(entity, replicate(16,sample(0:100,5,rep=TRUE)))
names(ge) <- c('entity', 
               'first_u7_2011','first_u7_2012','first_u7_2013','first_u7_2014',
               'first_79_2011','first_79_2012','first_79_2013','first_79_2014',
               'second_u7_2013','second_u7_2014',
               'second_79_2013','second_79_2014',
               'third_u7_2013','third_u7_2014',
               'third_79_2015','third_79_2016')

Gruppe <- c("Unter 7", "7-9 Jahre")
Kategorie <- c("first", "second", "third")

zeitraum.list <- list(jahre_first_u7 = c(2011:2014),
                      jahre_first_79 = c(2011:2014),
                      jahre_second_u7 = c(2013:2014),
                      jahre_second_79 = c(2013:2014),
                      jahre_third_u7 = c(2013:2014),
                      jahre_third_79 = c(2015:2016))


#UI Seite
ui <- fluidPage(
  titlePanel(""),
  sidebarLayout(position = "left",
                sidebarPanel(
                  selectInput("Gruppe", label = "Gruppe:", Gruppe),
                  selectInput("Kategorie", label = "Kategorie:", Kategorie),
                  uiOutput("Slider")),
                mainPanel("Tabelle", tableOutput("tableview"))))


#Server Seite
server <- function(input, output, session) {


  gruppe <- reactive({
    switch(input$Gruppe,
           "Unter 7" = select(ge, entity, matches("u7")),
           "7-9 Jahre" = select(ge, entity, matches("79")))
  })

  kategorie <- reactive({
    switch(input$Kategorie,
           "first" = select(gruppe(), entity, matches("first")),
           "second" = select(gruppe(), entity, matches("second")),
           "third" = select(gruppe(), entity, matches("third")))
  })

  zeitraum1 <- reactive({
    switch(input$Gruppe,
           "Unter 7" = zeitraum.list[c(1,3,5)],
           "7-9 Jahre" = zeitraum.list[c(2,4,6)])
  })

  zeitraum2 <- reactive({
    switch(input$Kategorie,
           "first" = zeitraum1()[[1]],
           "second" = zeitraum1()[[2]],
           "third" = zeitraum1()[[3]])
  })




  output$Slider <- renderUI({
    if (is.null(input$Kategorie))
      return()
    switch(input$Kategorie,
           "first" = sliderInput("inSlider", "Zeitleiste:",
                                           min = min(zeitraum2()),
                                           max = max(zeitraum2()),
                                           step = 1,
                                           value = min(zeitraum2()),
                                           sep = ""),
           "second" = sliderInput("inSlider", "Zeitleiste:",
                                            min = min(zeitraum2()),
                                            max = max(zeitraum2()),
                                            step = 1,
                                            value = min(zeitraum2()),
                                            sep = ""),
           "third" = sliderInput("inSlider", "Zeitleiste:",
                                            min = min(zeitraum2()),
                                            max = max(zeitraum2()),
                                            step = 1,
                                            value = min(zeitraum2()),
                                            sep = ""))

  })


  filtered <- eventReactive(req(input$inSlider, kategorie()), {
    if(input$inSlider == "2011"){filtered = select(kategorie(), entity, matches("2011"))}
    if(input$inSlider == "2012"){filtered = select(kategorie(), entity, matches("2012"))}
    if(input$inSlider == "2013"){filtered = select(kategorie(), entity, matches("2013"))}
    if(input$inSlider == "2014"){filtered = select(kategorie(), entity, matches("2014"))}
    if(input$inSlider == "2015"){filtered = select(kategorie(), entity, matches("2015"))}
    if(input$inSlider == "2016"){filtered = select(kategorie(), entity, matches("2016"))}
    return(filtered) 
  })


  output$tableview <- renderTable({
    table <- filtered()[, c(1,2)]
    head(table[, c(1,2)], n = 5)
  })

}

shinyApp(ui, server)

当用户输入更改为“Kategorie”或“Gruppe”输入时,始终会发生错误,其中最后一个滑块小部件的滑块值在新生成的滑块中不存在。例如:如果您运行应用程序并将“Kategorie”输入更改为“third”。 这对于传单对象来说是非常有问题的,因为应用程序不仅会抛出错误,而且还会完全崩溃。我很确定问题出现在eventReactive表达式中,因为在刚刚陈述的示例中,反应对象不知道如何忽略滑块范围内不存在的时间值的可能用户输入。

我怎样才能做到这一点?非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

使用req可以轻松解决您的问题。

当您想要从data-fram访问更多列时,问题就出现了。因此,只需添加req语句,检查数据框是否至少有2列,一切正常

output$tableview <- renderTable({
    req(ncol(filtered()) > 1)
    table <- filtered()[, c(1,2)]
    head(table[, c(1,2)], n = 5)
  })

希望这会有所帮助!!