График не рендеринга с входами на боковой панели Shinydashboard - PullRequest
2 голосов
/ 14 марта 2019

В течение нескольких дней я работал над приложением с библиотекой shiny, и теперь я хотел бы протестировать новые адаптации с пакетом shinydashboard. Проблема в том, что мой график не отображается (отображается) на вкладке, которую я хотел бы видеть при настройке входов на боковой панели.

Используя только блестящую упаковку, я установил следующий код без боковой панели меню (как в shinydashboard):

library(shiny)
library(ggplot2)
library(dplyr)

rm(list=ls()); gc()

#functions to order the bar graph

reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
  new_x <- paste(x, within, sep = sep)
  stats::reorder(new_x, by, FUN = fun)
}

scale_x_reordered <- function(..., sep = "___") {
  reg <- paste0(sep, ".+$")
  ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}

#setting example data 

sample_data = data.frame(Company_Name=c("Company 1","Company 2","Company 3",
                                        "Company 1","Company 2","Company 3",
                                        "Company 1","Company 2","Company 3"),
                         Profits_MM = c(20,100,80,
                                        45,120,70,
                                        50,110,130),
                         Sales_MM = c(200,800,520,
                                      300,1000,630,
                                      410,1150,1200),
                         Year=c(2016,2016,2016,
                                2017,2017,2017,
                                2018,2018,2018))


# UI
ui <- fluidPage(

  sidebarLayout(

    # Input(s)
    sidebarPanel(

      checkboxGroupInput(inputId = "sel_com",
                         label = "Company Selection:",
                         choices = c("Company 1","Company 2","Company 3"),
                         selected = "Company 1"),


      selectInput(inputId = "y", 
                  label = "Performance Variable",
                  choices = c("Profits (in Millions)" = "Profits_MM", 
                              "Sales (in Millions)" = "Sales_MM"),
                  selected = "Profits_MM"),


      sliderInput("year","Year Selection:",
                  min=2016,
                  max=2018,
                  value=c(2017,2018),
                  step=1)


    ),

    # Output(s)
    mainPanel(
      plotOutput(outputId = "barplot")
    )
  )
)

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

  companies_sel <- reactive({

    req(input$sel_com)

    sample_data_gg = filter(sample_data, Company_Name %in% input$sel_com)
    #  print(sample_data_gg)
    sample_data_gg

  })

  year_sample <- reactive({

    req(input$year)
    sample_data_gg = sample_data
    if((input$year[2] - input$year[1])>1){

      Years = seq(input$year[1],input$year[2])

      sample_data_gg = filter(companies_sel(), Year %in% Years)

    }  

    if((input$year[2] - input$year[1])==1){

      sample_data_gg = filter(companies_sel(), Year %in% input$year)

    }
    #  print(sample_data_gg)
    sample_data_gg
  })


  output$barplot = renderPlot({

    sample_data_gg = year_sample()

    y <- input$y
    ggplot(data = sample_data_gg, aes(x=reorder_within(Company_Name, get( y ), Year), y = get( y ))) +
      geom_col(position="dodge", fill="darkred") +
      facet_wrap(Year~., scales = "free")  +
      scale_x_reordered() +
      theme(axis.text.x = element_text(angle = 60, hjust = 1))


  })

}

shinyApp(ui = ui, server = server)

Этот код работает в блестящем пакете и показывает тип графика, который я хотел бы показать в приложении.

Но если я изменю эту кодировку для пакета shinydashboard - при настройке входов внутри боковой панели - график не появится, и я пытаюсь выяснить, почему. Вот это код:

library(shiny)
library(ggplot2)
library(dplyr)
library(shinydashboard)

reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
  new_x <- paste(x, within, sep = sep)
  stats::reorder(new_x, by, FUN = fun)
}

scale_x_reordered <- function(..., sep = "___") {
  reg <- paste0(sep, ".+$")
  ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}

rm(list=ls()); gc()

sample_data = data.frame(Company_Name=c("Company 1","Company 2","Company 3",
                                        "Company 1","Company 2","Company 3",
                                        "Company 1","Company 2","Company 3"),
                         Profits_MM = c(20,100,80,
                                        45,120,70,
                                        50,110,130),
                         Sales_MM = c(200,800,520,
                                      300,1000,630,
                                      410,1150,1200),
                         Year=c(2016,2016,2016,
                                2017,2017,2017,
                                2018,2018,2018))


# UI
ui <- dashboardPage(
      dashboardHeader(title = "Dashboard Test"),
      dashboardSidebar(

      sidebarMenu(id="tab",
                  menuItem("Data Selection", tabName = "dc", icon = icon("dashboard"),
      checkboxGroupInput(inputId = "sel_com",
                         label = "Company Selection:",
                         choices = c("Company 1","Company 2","Company 3"),
                         selected = "Company 1"),
      selectInput(inputId = "y", 
                  label = "Performance Variable",
                  choices = c("Profits (in Millions)" = "Profits_MM", 
                              "Sales (in Millions)" = "Sales_MM"),
                  selected = "Profits_MM"),
      sliderInput("year","Year Selection:",
                  min=2016,
                  max=2018,
                  value=c(2017,2018),
                  step=1)))),


      dashboardBody(

        tabItems(
          # First tab content
          tabItem(tabName = "dc",

                  fluidRow(column(width=12,box(plotOutput("plot1")))


        )
      )
    )
  )
)


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

  companies_sel <- reactive({

    req(input$sel_com)

    sample_data_gg = filter(sample_data, Company_Name %in% input$sel_com)
    #  print(sample_data_gg)
    sample_data_gg

  })

  year_sample <- reactive({

    req(input$year)
    sample_data_gg = sample_data
    if((input$year[2] - input$year[1])>1){

      Years = seq(input$year[1],input$year[2])

      sample_data_gg = filter(companies_sel(), Year %in% Years)

    }  

    if((input$year[2] - input$year[1])==1){

      sample_data_gg = filter(companies_sel(), Year %in% input$year)

    }
    #  print(sample_data_gg)
    sample_data_gg
  })


  output$barplot = renderPlot({

    sample_data_gg = year_sample()

    y <- input$y
    ggplot(data = sample_data_gg, aes(x=reorder_within(Company_Name, get( y ), Year), y = get( y ))) +
      geom_col(position="dodge", fill="darkred") +
      facet_wrap(Year~., scales = "free")  +
      scale_x_reordered() +
      theme(axis.text.x = element_text(angle = 60, hjust = 1))


  })

}

shinyApp(ui = ui, server = server)

Я полагаю, что мне может не хватать некоторого взаимодействия между графиком и выбором входа на боковой панели, но я не могу точно понять, что не так.

1 Ответ

4 голосов
/ 14 марта 2019

У вас на самом деле было несколько проблем в вашем коде, которые все вместе вызывали проблему:

Первый : первый был указан в комментариях - вы использовали rm(list=ls()) для удаления функций, которые вам понадобились позже.

Секунда : Ваш plotOutput() использовал идентификатор "plot1", в то время как ваш renderPlot имел в виду "barplot". Я предполагаю, что это была простая ошибка перевода с того момента, когда вы переключались на shinydashboard. Сделайте их такими же, и это поможет.

Третий : Это был более серьезный из трех. shinydashboard имеет известную проблему, очень хорошо описанную здесь , где несколько элементов в пределах menuItem вызывают потерю атрибутов, которые связывают содержимое с tabItem s. Вы можете преодолеть это с помощью пользовательской функции, которая устанавливает эти значения вручную, а затем обернуть ваши menuItem вызовы в эту функцию, заботясь о том, чтобы указать tabName в функции.

convertMenuItem <- function(mi,tabName) {
  mi$children[[1]]$attribs['data-toggle']="tab"
  mi$children[[1]]$attribs['data-value'] = tabName
  mi
}

Обновленный интерфейс для вашей ситуации будет выглядеть так:

ui <- dashboardPage(
      ... #Other elements remain unchanged
      dashboardSidebar(
        sidebarMenu(
          convertMenuItem(menuItem("Data Selection", tabName = "dc", icon = icon("dashboard"),
              checkboxGroupInput(inputId = "sel_com",
                                label = "Company Selection:",
                                choices = c("Company 1","Company 2","Company 3"),
                                selected = "Company 1"),
              selectInput(inputId = "y", 
                                 label = "Performance Variable",
                                 choices = c("Profits (in Millions)" = "Profits_MM", 
                                             "Sales (in Millions)" = "Sales_MM"),
                                 selected = "Profits_MM"),
              sliderInput("year","Year Selection:",
                          min=2016,
                          max=2018,
                          value=c(2017,2018),
                          step=1)), tabName="dc")
        )
      ),
     ... #Other elements remain unchanged
     )

enter image description here

...