Peter Nsanze
Peter Nsanze

Reputation: 69

R Shiny app sliderInput control x axis in GGplot

I have 25 cars in a race doing 58 laps.

Static plot showing all 58 laps

I want to have a slider that I want to control the laps seen in a chart as x axis in a ggplot.

UI:

sliderInput("lapsView",
              "Choose laps to view:",
              min = 1,
              max = 58,
              value = 10)

SERVER:

library(shiny)

shinyServer(function(input, output) {


  output$distPlot <- renderPlot({

    f1<- read.csv("F1 2011 Turkey - Fuel Corrected Lap Times.csv", header = T)

    str(f1)
    library(ggplot2)

    f1$Driver<-as.factor(f1$Driver)


    p1 <- ggplot(data=f1, 
                  aes(x = Lap, y= Lap.Time, colour = Driver)) + 
      ylim(80,100)+
      geom_line() + geom_point()                    

    # I combined p1 with p2 to save space.

    p2 <- p1  + coord_polar() 
    p2

  })

})

I'd like to change x=Lap to essentially x = sliderInput. I tried x = input$lapsView, but only get a single point for each.

Please help.

Result

Upvotes: 2

Views: 2525

Answers (1)

Michal Majka
Michal Majka

Reputation: 5471

If you really want to do it with a sliderInput you can do following:

  • change the value of the parameter value in the sliderInput from 10 to a vector c(1, 58)

  • create a sequence of integers with minimum and maximum given by the ranged slider

    lapsView <- seq(input$lapsView[1], input$lapsView[2])

  • do subsetting on f1. It is necessary because otherwise you would get vectors with a different length and ggplot would complain

    f1_new <- f1[which(f1$Lap %in% lapsView), ]

  • finally use a new dataset in ggplot

Ui.R

  sliderInput("lapsView",
              "Choose laps to view:",
              min = 1,
              max = 58,
              value = c(1, 58),
              dragRange = TRUE), 

  checkboxGroupInput("driverID", 
                     "Driver", 
                     c("Sebastian Vettel" = 1, "Mark Webber" = 2, 
                       "Fernando Alonso" = 3, "Lewis Hamilton" = 4, 
                       5, 6, 7, 8, 9, 10, 11, 12 ,13 ,14, 15, 16, 17, 18, 19, 20, 21, 22, 23,24,25),
                     selected = FALSE, inline = FALSE, width = NULL)

Server.R

library(shiny)
library(DT)
server <- shinyServer(function(input, output) {

    output$distPlot <- renderPlot({

      f1 <- read.csv("F1 2011 Turkey - Fuel Corrected Lap Times.csv", header = T)

      f1$Driver <- as.factor(f1$Driver)

      lapsView <- seq(input$lapsView[1], input$lapsView[2]) 

      # driverID <- seq(input$driverID[1], input$driverID[2]) 
      driverID <- input$driverID  
      req(driverID) # require that driverID is not NULL - it would break down the code below

      # Subsetting: 
      f1_new <- f1[which(f1$Lap %in% lapsView & f1$Driver %in% driverID),] 
      p1 <- ggplot(data = f1_new, aes(x = Lap, y = Lap.Time, colour = Driver)) + 
        ylim(80, 100)+ geom_line() + geom_point()
      p2 <- p1 + coord_polar() 
      p2

    })

    observe({
      # input$lapsView returns in this case two values - minimum and maximum 
      # (initially 1 and 58)
      # If we used these values we would have only two points - 1 and 58
      # As we want to have all points in between 1 and 58 we create a sequence
      # with the function `seq`.
      # If you wanted to have a sequence in which starting value differs and 
      # maximum is always given by 58 you could do following:

      #  sliderInput:
      # - remove dragRange = TRUE 
      # - change value from c(1,58) to 1
      #  server
      # - lapsView <- seq(input$lapsView[1], 58) 


      # You want to add another condition to subsetting. It looks fine but 
      # you should change 
      # driverID <- seq(input$driverID[1], input$driverID[2])
      # to 
      # driverID <- input$driverID 
      # because input$driverID alrady contains all choices
      # You have to be careful about the case when there is nothing checked.
      # driverID yields in this case NULL
      # It may break down the code so it is good to use the function `req`


      # Here you can observe values of inputs in the console. It is a 
      # good way to see "what's going on" and to debug the code.

      print(" ================================================== ")
      print("Input$driverID")
      print(input$driverID)

      print("---------------")
      print("input$lapsView")
      print(input$lapsView)
      # two values - min and max

      print(" ================================================== ")
      print('')
      print('')
      print('')

    })

  })

Upvotes: 2

Related Questions