努力在Shiny中设置多步SelectInput

您可以看到我正在尝试设置三个不同的过滤器,它们都相互反应,但是当我测试它时,它总是给我错误。

我要完成的工作就是以说我选择“地区1”的方式来设置这些过滤器,它会给我相应的州(俄亥俄州)和城市(哥伦布和克利夫兰) )。同时,假设我同时选择了区域1和4,它将为我提供各州(俄亥俄州和密歇根州)和城市(哥伦布,克利夫兰和大瀑布城,但没有底特律)。同时,假设我想忽略“领域”字段并决定直接进入“州”过滤器,它将为我提供所有州选项(请记住,我尚未选择任何领域)。如果我只是想直接进入城市过滤器,那也是一样。

因此,基本上,我希望所有过滤器相互反应联系在一起,但又没有严格的层次结构,因此我必须先选择地区,然后再选择州,最后再选择城市。

我能很好地解释吗?

这是代码。

设置:

library(shiny)
library(dplyr)
library(highcharter)

df <- structure(list(territory = structure(c(1L,1L,2L,3L,4L
),.Label = c("1","2","3","4"),class = "factor"),state = structure(c(3L,2L),.Label = c("Indiana","Michigan","Ohio"
                                                                          ),city = structure(c(2L,6L,4L,5L),.Label = c("Cleveland","Columbus","Detroit","Gary","Grand Rapids","Indianapolis"),sales = 5:10,leads = 11:16),class = "data.frame",row.names = c(NA,-6L)) %>%
  mutate_all(as.character)

ui <- {
  fluidPage(
    fluidRow(
      selectizeInput(
        inputId = 'selectTerritory',label = 'Select Territory',choices = c('All Territories',sort(unique(df$territory))),multiple = TRUE,selected = 'All Territories'),uiOutput(
        outputId = 'selectState'),uiOutput(
        outputId = 'selectCity'),highchartOutput("test")
      # plotOutput()
    )
  )
}

server <- function(input,output,session) {

  output$selectState <- renderUI({
    # if 'All Territories' is not selected,then filter df by selected Territories. Otherwise,just get all states.
    if (!('All Territories' %in% input$selectTerritory)) {
      df <- df %>%
        filter(
          territory %in% input$selectTerritory)
    }
    states <- sort(unique(df$state))
    selectizeInput(
      inputId = 'selectState',label = 'Select State',choices = c('All States',states),selected = 'All States')
  })

  output$selectCity <- renderUI({
    # same strategy
    if (!('All States' %in% input$selectState)) {
      df <- df %>%
        filter(
          state %in% input$selectState,territory %in% input$selectTerritory)
    } else {
      df <- df %>%
        filter(
          territory %in% input$selectTerritory)
    }
    cities <- sort(unique(df$city))
    selectizeInput(
      inputId = 'selectCity',label = 'Select City',choices = c('All Cities',cities),selected = 'All Cities')
  })

  geog <- reactive({

    res <- df %>% filter(is.null(input$selectTerritory) | territory %in% input$selectTerritory,is.null(input$selectState) | state %in% input$selectState,is.null(input$selectCity) | city %in% input$selectCity)
  })

  output$test <- renderHighchart({

    res <- geog() %>% select_all() 

    graph <- res %>% group_by_all() %>% summarise(totals=sum(sales))

    highchart() %>% hc_add_series(data = graph,type = "bar",hcaes(y = totals),showInLegend = TRUE) %>% hc_add_theme(hc_theme_flat())

  })
}

shinyApp(ui,server)
poee223 回答:努力在Shiny中设置多步SelectInput

首先,我更喜欢单文件Shiny应用程序(复制/粘贴整个应用程序要比将ui和服务器使用单独的文件容易得多)。 单文件Shiny应用程序的另一个好处是,当您将代码发布到Stack Overflow之类的东西时,您只需复制并粘贴整个内容,包括对library()的调用就非常重要!例如,我不知道您在highChartOutput()中使用什么软件包,因此包含这些library()调用使人们在重现您的代码时更加容易(如果您只有一个单包,文件闪亮的应用程序)。在相关说明中,您的问题实际上与绘图输出没有任何关系,因此我在这里忽略了该部分(您应该能够像在Shiny应用程序中一样访问输出)。 / p>

第二,我不会使用rbind()来创建df(它可以对数据类型进行奇怪的处理)。您只需定义变量列,然后直接调用data.frame()(例如df <- data.frame(v1,v2))即可。我通过定义变量列,调用data.frame然后运行dput(df)来创建可重现的数据,这意味着我们可以在一个调用中定义您的数据框(因此很容易重现并避免任何错别字)

第三,我正在使用dplyr::mutate_all(as.character),因为我不知道您为此使用的软件包(taRifx)。

最后,回答您的问题...我要解决此问题的方法是为每个类定义与“所有变量”有效对应的额外变量,并为每个selectizeInput选择默认变量。

library(shiny)
library(dplyr)

df <- structure(list(territory = structure(c(1L,1L,2L,3L,4L
    ),.Label = c("1","2","3","4"),class = "factor"),state = structure(c(3L,2L),.Label = c("Indiana","Michigan","Ohio"
    ),city = structure(c(2L,6L,4L,5L),.Label = c("Cleveland","Columbus","Detroit","Gary","Grand Rapids","Indianapolis"),sales = 5:10,leads = 11:16),class = "data.frame",row.names = c(NA,-6L)) %>%
    mutate_all(as.character)

ui <- {
    fluidPage(
        fluidRow(
            selectizeInput(
                inputId = 'selectTerritory',label = 'Select Territory',choices = c('All Territories',sort(unique(df$territory))),multiple = TRUE,selected = 'All Territories'),uiOutput(
                outputId = 'selectState'),uiOutput(
                outputId = 'selectCity')
            # plotOutput()
        )
    )
}

server <- function(input,output,session) {

    output$selectState <- renderUI({
        # if 'All Territories' is not selected,then filter df by selected Territories. Otherwise,just get all states.
        if (!('All Territories' %in% input$selectTerritory)) {
            df <- df %>%
                filter(
                    territory %in% input$selectTerritory)
        }
        states <- sort(unique(df$state))
        selectizeInput(
            inputId = 'selectState',label = 'Select State',choices = c('All States',states),selected = 'All States')
    })

    output$selectCity <- renderUI({
        # same strategy
        if (!('All States' %in% input$selectState)) {
            df <- df %>%
                filter(
                    state %in% input$selectState,territory %in% input$selectTerritory)
        } else {
            df <- df %>%
                filter(
                    territory %in% input$selectTerritory)
        }
        cities <- sort(unique(df$city))
        selectizeInput(
            inputId = 'selectCity',label = 'Select City',choices = c('All Cities',cities),selected = 'All Cities')
    })
}

shinyApp(ui,server)
本文链接:https://www.f2er.com/2931089.html

大家都在问