简体   繁体   中英

Shiny R plots only extreme values of slider range

I would like to create a Shiny app with the time-series graph, where x-axis (Years) is based on the slider range input, and y-axis is a variable (also based on select input). However, when I produce the plot, only extreme (min and max) values are reflected on the plot, the years within the interval of years are seem to be omitted.

The code works perfectly when I don't use slider for years, the plot produces a plausible time-trend. However, I need to implement it with the slider and would appreciate much any proposals.

Here is my code.

UI

 `
    library(shiny)
    library(ggplot2)
    library(readxl)
    library(plotly)
    library(dplyr)

dat <<- read_excel("~/R/data.xlsx")

ui <- fluidPage(

  titlePanel("Data, 1990-2017"),

  sidebarLayout(
   # Inputs
      sidebarPanel(

  h3("Select Variable"),    
  # Select variable for y-axis
  selectInput(inputId = "y", 
              label = "Y-axis:",
              choices = c("Estimate", "Male", "Female"), 
              selected = "Estimate"),

  hr(),

  h3("Subset by Region"),    

  # Select which types of movies to plot
  selectInput(inputId = "Region",
              label = "Select Region:",
              choices = c("Africa", "Americas", "Asia", "Europe", "Oceania", "World"),
              selected = "World"), 

  hr(),

  h3("Year range"),    

  sliderInput(inputId = "slider", 
              label = "Years",
              min = 1990, 
              max = 2017, 
              sep = "",
              step = 1,
              value = c(1990, 2017))

),



mainPanel(

  tabsetPanel(type = "tabs",
              id = "tabsetpanel",
              tabPanel(title = "Plot", 
                       plotlyOutput(outputId = "tsplot"),
                       br(),
                       h5(textOutput("description")))
   )
  )
 )
)

`

Server

`
server <- function(input, output) {

     regions <- reactive({
     req(input$Region)
     req(input$slider) 

dat %>%
  filter(Region_Name %in% input$Region 
         & Year %in% input$slider) 


})


   output$tsplot <- renderPlotly({
    p <-  ggplot(data = regions(), 
                 aes_string(x = input$slider, y = input$y))+
          geom_line() +
          geom_point()+
          theme(legend.position='none') 

    ggplotly(p)
  })
}


shinyApp(ui = ui, server = server)

`

That's how the output looks like

app output

input$slider is the range (the two extreme values). If you want all the years contained in this range, do seq(input$slider[1], input$slider[2], by = 1) . You can do:

server <- function(input, output) {

  years <- reactive({
    seq(input$slider[1], input$slider[2], by = 1)
  })

  regions <- reactive({
    # req(input$Region)  these two req are not necessary
    # req(input$slider) 

    dat %>%
      filter(Region_Name %in% input$Region & Year %in% years()) 
  })

   output$tsplot <- renderPlotly({
    p <-  ggplot(data = regions(), 
                 aes_string(x = Year, y = input$y)) +
          geom_line() +
          geom_point() +
          theme(legend.position='none') 

    ggplotly(p)
  })
}

Many thanks! it did work for the plot! However, I needed to advance the app by creating a second tabset with the wide data table. Is it possible, to do use range slider for selecting years as columns in a wide data table? Would appreciate any proposals. Based on the previous solution, I wrote this:

dat <<- read_excel("~/R/World estimates.xlsx")

datwide <<- read.csv("~/R/selected shiny.csv", check.names=FALSE)

ui <- fluidPage(
   pageWithSidebar(

headerPanel("Data, 1990-2017"),

sidebarPanel(



  conditionalPanel(
    condition = "input.theTabs == 'firstTab' ",

    h3('Time Series Plot '),
    selectInput(inputId = "y", 
                label = "Y-axis:",
                choices = c("Estimate", "Male", "Female"), 
                selected = "Estimate"),

    # Select which types of movies to plot
    selectInput(inputId = "Region",
                label = "Select Region:",
                choices = c("Africa", "Americas", "Asia", "Europe", "Oceania", "World"),
                multiple = TRUE,
                selected = "World")
    ,

    h3("Year range"),    # Third level header: Years

    sliderInput(inputId = "slider", 
                label = "Years",
                min = 1990, 
                max = 2017, 
                sep = "",
                step = 1,
                value = c(1990, 2017))
    ),


    conditionalPanel(
      condition = "input.theTabs == 'secondTab' ",
      h3('Data Table'),
      selectInput(inputId = "Region1",
                  label = "Select Region:",
                  choices = c("Africa", "Americas", "Asia", "Europe", "Oceania", "World"),
                  multiple = TRUE,
                  selected = "World"), 

      selectInput(inputId = "Indicator",
                  label = "Select Indicator(s):",
                  choices = c("Estimated Count", "Estimated male", "Estimated 
                  female"),
                  multiple = TRUE,
                  selected = "Estimated Count"),

      sliderInput(inputId = "sliderData", 
                  label = "Years",
                  min = 1990, 
                  max = 2017, 
                  sep = "",
                  step = 1,
                  value = c(2007, 2017)),

       downloadButton(outputId = "download_data", 
                      label = "Download Selected Data")

       ),

    conditionalPanel(
      condition = "input.theTabs == 'thirdTab' ",
      h3("Maps")

  )

  ),

  mainPanel(
    tabsetPanel(
      tabPanel( "Time series", plotlyOutput("timeSeries"),  
                value = "firstTab"),
      tabPanel( "Data", DT::dataTableOutput("datatab"),
                value = "secondTab"),
      tabPanel( "Maps", plotOutput("map"),
                value = "thirdTab"),
      id = "theTabs"
    )
   )
  )
 ) 

And for the server:

   server <- function(input, output) {

   years <- reactive({
    seq(input$slider[1], input$slider[2], by = 1)
    })

 regions <- reactive({

dat %>%
  filter(Region_Name %in% input$Region & Year %in% years()) 
 }) 


output$timeSeries <- renderPlotly({

p <- ggplot(data = regions(), aes_string( x = 'Year', y = input$y))+
  geom_line(aes(color = Region_Name)) +
  geom_point()


ggplotly(p)
})

years2 <- reactive({
  seq(input$sliderData[1], input$sliderData[2], by = 1)
}) 

output$datatab  <- DT::renderDataTable({


d <-   
 datwide %>%
 filter(Region %in% input$Region1 &
          Variable %in% input$Indicator) %>% 
  select(Region, Variable, years2 %in% input$sliderData)

 d
 })

# Create a download handler
output$download_data <- downloadHandler(

filename = "selected_data.csv",
content = function(file) {

  datwide %>%
 filter(Region %in% input$Region1 &
          Variable %in% input$Indicator) %>% 
  select(Region, Variable, years2 %in% input$sliderData)

  d 
  # Write the filtered data into a CSV file
  write.csv(d, file, row.names = FALSE)
   }
  )
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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