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