如何使动态输入同时工作

时间:2018-09-05 11:46:11

标签: r input shiny

我有一个简单的shiny app,仅绘制一个chart。我的data frame (df)包含范围不同的variables,例如:Year, Month, Category, Brand。 在绘制图表时,我想根据上面列出的所有变量对数据进行切片,因此我将它们设置为dynamic inputs。我有一个有效的代码,但是,此应用需要一些改进:

对于CategoryBrand之类的变量,我做了一个额外的变量All,该变量将所有类别/品牌绘制在一起。该值All已在应用程序中预先选择。 c("All", sort(unique(as.character(df$Brand))))

  1. 在此app中,我有4个不同的input variables:年,月,类别,品牌。当我尝试不同的输入组合时,大多数情况下,一个输入会重置另一个输入。 F.e.如果我选择Year:2018,Months:1-6,然后再次将Year更改为2015,则此更改会将Month和所有其他输入重置为默认值。有什么解决方案可以使其同时工作?

  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)

0 个答案:

没有答案