简体   繁体   English

是否可以通过 R Shiny 中的 outputId 进行过滤?

[英]Is it possible to filter by an outputId in R Shiny?

I have made a simple Shiny App with a plotly drilldown chart.我制作了一个简单的 Shiny 应用程序,其中包含 plotly 下钻图表。 As of right now I have Project Sub-Level as a SelectInput variable.截至目前,我将 Project Sub-Level 作为 SelectInput 变量。 That is because I need the sublevel as a filtering device and I only know how to filter with inputIds (filter %in% input$x, etc, etc).那是因为我需要子级别作为过滤设备,而且我只知道如何使用 inputIds 进行过滤(过滤 %in% input$x 等)。

However, I do not want the user of this app to actually select the sublevel.但是,我不希望这个应用程序的用户实际上是 select 子级别。 I just want it auto-populated based on its corresponding main level.我只想根据相应的主级别自动填充它。

Is there a way to make it like a verbatimtextoutput but still use it as a filtering device?有没有办法让它像 verbatimtextoutput 但仍将其用作过滤设备?

Or is there a way I can disable the SelectInput aspect so it doesn't look like the user can actually select the sublevel?或者有没有一种方法可以禁用 SelectInput 方面,这样它看起来不像用户实际上可以 select 子级别?

As always any and all help is appreciated.一如既往,我们将不胜感激。 Thank you.谢谢你。

library(tidyverse)
library(plotly)
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(shinyjs)


full_data <- tibble(
  Project_Level = c(0,1,1,2,2,2,2, 0,1,1,2,2,2,2),
  Project_Sublevel = c(1,2,2,3,3,3,3, 1,2,2,3,3,3,3),
  Project_Type = c("House", "Bedrooms", "Bathrooms", "Bed", "Closet", "Toliet", "Shower",
                   "House", "Bedrooms", "Bathrooms", "Bed", "Closet", "Toliet", "Shower"),
  Project_Scope = c("None", "House", "House", "Bedrooms", "Bedrooms", "Bathrooms", "Bathrooms",
                    "None", "House", "House", "Bedrooms", "Bedrooms", "Bathrooms", "Bathrooms"),
  Year = c("2008", "2008", "2008", "2008", "2008", "2008", "2008",
           "2009", "2009", "2009", "2009", "2009", "2009", "2009"),
  Cost = c(1000, 500, 500, 250, 250, 250, 250, 
           2000, 1000, 1000, 500, 500, 500, 500)
)


ui <- fluidPage(
  useShinyjs(),
  selectInput(
    inputId = "year",
    label = "Year",
    multiple = TRUE,
    choices = unique(full_data$Year),
    selected = unique(full_data$Year)
  ),
  selectInput(
    inputId = "project_level",
    label = "Project Level",
    multiple = FALSE,
    choices = unique(full_data$Project_Level),
    selected = "0"
  ),
  selectInput(
    inputId = "project_sublevel",
    label = "Project Sub-Level",
    multiple = FALSE,
    choices = unique(full_data$Project_Sublevel)
  ),
  plotlyOutput("housing_cost", height = 400),
  shinyjs::hidden(actionButton("clear", "Return to Project Level"))
)


server <- function(input, output, session) {
  
  
  observeEvent({
    input$project_level
  },
  handlerExpr = {
    if (input$project_level == "<select>") {
      choicr <- ""
    } else {
      choice <- as.numeric(input$project_level) + 1
    }
    updateSelectInput(
      session = session,
      inputId = "project_sublevel",
      choices = choice
    )
  })
  
  
  
  
  
  drills <- reactiveValues(category = NULL,
                           sub_category = NULL)
  
  
  house_reactive <- reactive({
    full_data %>%
      filter(Year %in% input$year) %>%
      filter(Project_Level %in% input$project_level)
  })
  
  
  house_reactive_2 <- reactive({
    full_data %>%
      filter(Year %in% input$year) %>%
      filter(Project_Level %in% input$project_sublevel) %>%
      filter(Project_Scope %in% drills$category)
  })
  
  
  house_data <- reactive({
    if (is.null(drills$category)) {
      return(house_reactive())
    }
    else {
      return(house_reactive_2())
    }
  })
  
  
  output$housing_cost <- renderPlotly({
    if (is.null(drills$category)) {
      plot_title <- paste0("Cost of Project Level Components")
    } else {
      plot_title <- paste0("Cost of ",  drills$category)
    }
    
    
    house_data() %>%
      plot_ly(
        x = ~ Year,
        y = ~ Cost,
        color = ~ Project_Type,
        key = ~ Project_Type,
        source = "housing_cost",
        type = "bar"
      ) %>%
      layout(
        barmode = "stack",
        showlegend = T,
        xaxis = list(title = "Year"),
        yaxis = list(title = "Cost"),
        title = plot_title
      )
  })
  
  
  observeEvent(event_data("plotly_click", source = "housing_cost"), {
    x <- event_data("plotly_click", source = "housing_cost")$key
    if (is.null(x))
      return(NULL)
    if (is.null(drills$category)) {
      drills$category <- unlist(x)
    }  else {
      drills$sub_category <- NULL
    }
  })
  
  
  observe({
    if (!is.null(drills$category)) {
      shinyjs::show("clear")
    }
  })
  
  
  observeEvent(c(input$clear, input$project_level), {
    drills$category <- NULL
    shinyjs::hide("clear")
  })
}


shinyApp(ui, server)

you could change your Project Sub-Level SelectInput by a tableOutput, for example.例如,您可以通过 tableOutput 更改您的项目子级SelectInput In your server include a RenderTable associated that show filtered Project Sub-Level from house_reactive table:在您的服务器中包含一个关联的RenderTable ,它显示来自 house_reactive 表的过滤项目子级别:

library(tidyverse)
library(plotly)
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(shinyjs)


full_data <- tibble(
  Project_Level = c(0,1,1,2,2,2,2, 0,1,1,2,2,2,2),
  Project_Sublevel = c(1,2,2,3,3,3,3, 1,2,2,3,3,3,3),
  Project_Type = c("House", "Bedrooms", "Bathrooms", "Bed", "Closet", "Toliet", "Shower",
                   "House", "Bedrooms", "Bathrooms", "Bed", "Closet", "Toliet", "Shower"),
  Project_Scope = c("None", "House", "House", "Bedrooms", "Bedrooms", "Bathrooms", "Bathrooms",
                    "None", "House", "House", "Bedrooms", "Bedrooms", "Bathrooms", "Bathrooms"),
  Year = c("2008", "2008", "2008", "2008", "2008", "2008", "2008",
           "2009", "2009", "2009", "2009", "2009", "2009", "2009"),
  Cost = c(1000, 500, 500, 250, 250, 250, 250, 
           2000, 1000, 1000, 500, 500, 500, 500)
)


ui <- fluidPage(
  useShinyjs(),
  selectInput(
    inputId = "year",
    label = "Year",
    multiple = TRUE,
    choices = unique(full_data$Year),
    selected = unique(full_data$Year)
  ),
  selectInput(
    inputId = "project_level",
    label = "Project Level",
    multiple = FALSE,
    choices = unique(full_data$Project_Level),
    selected = "0"
  ),
  # selectInput(
  #   inputId = "project_sublevel",
  #   label = "Project Sub-Level",
  #   multiple = FALSE,
  #   choices = unique(full_data$Project_Sublevel)
  # ),
  tags$h3("Project Sub-Level"),
  tableOutput('project_sublevelt'),
  plotlyOutput("housing_cost", height = 400),
  shinyjs::hidden(actionButton("clear", "Return to Project Level"))
)


server <- function(input, output, session) {
  
  
  observeEvent({
    input$project_level
  },
  handlerExpr = {
    if (input$project_level == "<select>") {
      choicr <- ""
    } else {
      choice <- as.numeric(input$project_level) + 1
    }
    updateSelectInput(
      session = session,
      inputId = "project_sublevel",
      choices = choice
    )
  })
  
    output$project_sublevelt<- renderTable({
      unique(house_reactive()$Project_Sublevel)
   })
  
  
  
  drills <- reactiveValues(category = NULL,
                           sub_category = NULL)
  
  
  house_reactive <- reactive({
    full_data %>%
      filter(Year %in% input$year) %>%
      filter(Project_Level %in% input$project_level)
  })
  
  
  house_reactive_2 <- reactive({
    full_data %>%
      filter(Year %in% input$year) %>%
      filter(Project_Level %in% input$project_sublevel) %>%
      filter(Project_Scope %in% drills$category)
  })
  
  
  house_data <- reactive({
    if (is.null(drills$category)) {
      return(house_reactive())
    }
    else {
      return(house_reactive_2())
    }
  })
  
  
  output$housing_cost <- renderPlotly({
    if (is.null(drills$category)) {
      plot_title <- paste0("Cost of Project Level Components")
    } else {
      plot_title <- paste0("Cost of ",  drills$category)
    }
    
    
    house_data() %>%
      plot_ly(
        x = ~ Year,
        y = ~ Cost,
        color = ~ Project_Type,
        key = ~ Project_Type,
        source = "housing_cost",
        type = "bar"
      ) %>%
      layout(
        barmode = "stack",
        showlegend = T,
        xaxis = list(title = "Year"),
        yaxis = list(title = "Cost"),
        title = plot_title
      )
  })
  
  
  observeEvent(event_data("plotly_click", source = "housing_cost"), {
    x <- event_data("plotly_click", source = "housing_cost")$key
    if (is.null(x))
      return(NULL)
    if (is.null(drills$category)) {
      drills$category <- unlist(x)
    }  else {
      drills$sub_category <- NULL
    }
  })
  
  
  observe({
    if (!is.null(drills$category)) {
      shinyjs::show("clear")
    }
  })
  
  
  observeEvent(c(input$clear, input$project_level), {
    drills$category <- NULL
    shinyjs::hide("clear")
  })
}


shinyApp(ui, server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM