Как заставить динамические входы работать одновременно - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть простой shiny app, который отображает только один chart. Мой data frame (df) включает в себя диапазон различных variables, таких как: Year, Month, Category, Brand. При построении графика я хочу разделить данные в зависимости от всех перечисленных выше переменных, поэтому я сделал их как dynamic inputs. У меня есть рабочий код, однако, это приложение нуждается в некоторых улучшениях:

Для таких переменных, как Category и Brand, я создал дополнительную переменную All, которая отображает все категории / бренды вместе. Это значение All предварительно выбирается в приложении. c("All", sort(unique(as.character(df$Brand)))).

  1. В этом app у меня есть 4 разных input variables: год, месяц, категория, бренд. Когда я пробую разные комбинации входов, в большинстве случаев один вход сбрасывает другой. F.E. если я выберу Год: 2018, Месяцы: 1-6 и затем снова изменим Год на 2015, это изменение сбрасывает Месяц и все другие входные данные по умолчанию. Есть ли какое-нибудь решение, чтобы оно работало одновременно?

  2. Вторая проблема - когда я выбираю конкретную категорию / бренд. Значение All все еще остается выбранным, несмотря на то, что я выбираю другое конкретное значение. Есть ли способ отменить выбор All при выборе другого конкретного значения?

Также я включил рабочий код, чтобы лучше понять проблему, которую хочу решить:

library(shiny)
library(shinydashboard)
library(plyr)
library(ggplot2)



# Header -----------------------------------------------------------

header <- dashboardHeader(title= "DashBoard")


# Sidebar --------------------------------------------------------------

sm <- sidebarMenu(

  menuItem(
    text="Chart",
    tabName="chart",
    icon=icon("eye")
  )  

)

sidebar <- dashboardSidebar(sm)

# Body --------------------------------------------------

body <- dashboardBody(

  # Layout  --------------------------------------------  

  tabItems(


    tabItem(
      tabName="chart",
      fluidPage(

        fluidRow(

          title = "Inputs", status = "warning", width = 2, solidHeader = TRUE, collapsible = TRUE,


          uiOutput("Year"),
          uiOutput("Month.Range"),
          uiOutput("Category"),
          uiOutput("Brand"),
          plotOutput("Chart")



        )
      )
    )
  )
)

# Setup Shiny app UI components -------------------------------------------

ui <- dashboardPage(header, sidebar, body)

# Setup Shiny app back-end components -------------------------------------

server <- function(input, output) {

  # ----------------------------------------------------------------------------- 
  #reproducable data generation
    set.seed(1992)
    n=100

    Year <- sample(2015:2018, n, replace = TRUE)
    Month <- sample(1:12, n, replace = TRUE)
    Category <- sample(c("Car", "Bus", "Bike"), n, replace = TRUE, prob = NULL)
    Brand <- sample("Brand", n, replace = TRUE, prob = NULL)
    Brand <- paste0(Brand, sample(1:14, n, replace = TRUE, prob = NULL))
    USD <- abs(rnorm(n))*100

    df <- data.frame(Year, Month, Category, Brand, USD)


    #----------------------------------------------------------------------------
    #Generate input filters

    #Year filter
    output$Year <- renderUI({
      selectInput("Year", 
                  "Year:", 
                  c(unique(as.character(df$Year))), selected = max(unique(as.character(df$Year))))
    })

    #Month filter
    output$Month.Range <- renderUI({
      df <- df[df$Year %in% input$Year,]
      sliderInput("Month.Range", "Months:",
                  min = 1, max = max(unique(df$Month)), value = c(1, max(unique(df$Month))), step = 1)
    })    


    #Category filter
    output$Category<- renderUI({
      df <- df[df$Year %in% input$Year,]
      df <- df[df$Month >= input$Month.Range[1] & df$Month <= input$Month.Range[2],]
      selectizeInput("Category", 
                     "Category:", 
                     choices = c("All", sort(unique(as.character(df$Category)))), multiple = T, selected = "All")
    })

    #Brand filtras
    output$Brand <- renderUI({
      df <- df[df$Year %in% input$Year,]
      df <- df[df$Month >= input$Month.Range[1] & df$Month <= input$Month.Range[2],]
      if(!"All" %in% input$Category){
            df <- df[df$Category %in% input$Category,]
      }
      selectizeInput("Brand", 
                     "Brand:", 
                     choices = c("All", sort(unique(as.character(df$Brand)))), multiple = T, selected = "All")
    })


    #----------------------------------------------------------------------------
    #Data manipulation and plotting
    output$Chart <- renderPlot({


              df <- df[df$Year %in% input$Year,]

              #conditional to draw one or multiple categories
              if(!"All" %in% input$Category){
                df <- df[which(df$Category == input$Category),]
              }

              #conditional to draw one or multiple brands
              if(!"All" %in% input$Brand){
                df <- df[which(df$Brand %in% input$Brand),]
              }


              #aggredated data for plotting
              df <- ddply(df, c("Year", "Month", "Brand"), summarise, 
                          "USD" = sum(USD)/1000)
              df = ddply(df, .(Month), transform, pos = cumsum(USD) - 0.5*USD)



              #Chart
              ggplot(df, aes(x=factor(Month,levels=1:12), y=USD, fill=Brand))+
                geom_bar(stat='identity',  width = .7, colour="black", lwd=0.1)+
                scale_x_discrete('Month', breaks=factor(1:12), drop=FALSE) +
                ylab("Thousands of USD")+
                geom_text(aes(label=ifelse(USD > 1, paste(round(USD,0),""),"")), colour="white", size = 6, fontface = "bold", 
                          position=position_stack(vjust=0.5))

   })

   # -----------------------------------------------------------------------------


}

# Render Shiny app --------------------------------------------------------

shinyApp(ui, server)
...