5.14 Getting help (using Reprex)

  • If you cant debug the error, it is time to ask for help at Shiny Community by creating Reprex

  • A reprex is just some R code that works when you copy and paste it into a R session on another computer

  • Good reprex, makes it easy for others to help you debug your app

  • Below is an example of Shiny reprex

5.14.1 How to make a reprex

  • Create a single self-contained file that contains everything needed to run your code (e.g load all packages)

  • Test it by restarting fresh R session and then running the code

  • Potential problem is sharing your data

    • Use built-in datasets(mpg),
    • create sample datasets and illustrate the problem,
    • use subset of the data with dput()
(mydata <- data.frame(x = 1:5, y = c("a", "b", "c", "d", "e")))
##   x y
## 1 1 a
## 2 2 b
## 3 3 c
## 4 4 d
## 5 5 e
dput(mydata)
## structure(list(x = 1:5, y = c("a", "b", "c", "d", "e")), class = "data.frame", row.names = c(NA, 
## -5L))
  • Last resort is to provide complete app.R and the needed data files using Gihub or Zip files (if reading data from disk seems irreducible part of the problem)

  • Make sure you use relative paths

  • Format your code for to be easy read

5.14.2 Making a minimal reprex

  • Trim out all the code that’s ok (make the life of a helper much easier) rather than forcing a potential helper to understand your entire app.

  • This process often lead you to discover what the problem is, so you don’t have to wait for help from someone else!

  • A good way to find error code is to remove sections of code from your application, piece by piece, until the problem goes away

  • If removing a particular piece of code makes the problem stop, it’s likely that that code is related to the problem.

5.14.2.1 Example of Bad reprex

  • all the needed packages are not loaded
  • The code is not style, making it uneasy to help
library(shiny)

shinyApp(
  ui = fluidPage(
    uiOutput("interaction_slider"),
    verbatimTextOutput("breaks")
  ),
  
  server = function(input, output, session) {
    
    df <- data.frame (dateTime = c("2019-08-20 16:00:00",
                   "2019-08-20 16:00:01",
                   "2019-08-20 16:00:02",
                   "2019-08-20 16:00:03",
                   "2019-08-20 16:00:04",
                   "2019-08-20 16:00:05"),
      var1 = c(9, 8, 11, 14, 16, 1),
      var2 = c(3, 4, 15, 12, 11, 19),
      var3 = c(2, 11, 9, 7, 14, 1)
    )
    
    timeSeries <- as.xts(df[,2:4],order.by=strptime(df[,1], format="%Y-%m-%d %H:%M:%S"))
    print (paste(min(time(timeSeries)),is.POSIXt(min(time(timeSeries))),sep=' '))
    print (paste(max(time(timeSeries)),is.POSIXt(max(time(timeSeries))),sep=' '))
    
    output$interaction_slider <- renderUI({
      sliderInput(
        "slider",

5.14.2.2 Making the bad reprex better(minimal)

  • loaded needd packages
  • The code is style, making it easy to help
library(xts)
library(lubridate)
library(shiny)

ui <- fluidPage(
  uiOutput("interaction_slider"),
  verbatimTextOutput("breaks")
)
server <- function(input, output, session) {
  df <- data.frame(
    dateTime = c(
      "2019-08-20 16:00:00",
      "2019-08-20 16:00:01",
      "2019-08-20 16:00:02",
      "2019-08-20 16:00:03",
      "2019-08-20 16:00:04",
      "2019-08-20 16:00:05"
    ),
    var1 = c(9, 8, 11, 14, 16, 1),
    var2 = c(3, 4, 15, 12, 11, 19),
    var3 = c(2, 11, 9, 7, 14, 1)
  )

  timeSeries <- as.xts(df[, 2:4], 
    order.by = strptime(df[, 1], format = "%Y-%m-%d %H:%M:%S")
  )
  print(paste(min(time(timeSeries)), is.POSIXt(min(time(timeSeries))), sep = " "))
  print(paste(max(time(timeSeries)), is.POSIXt(max(time(timeSeries))), sep = " "))

  output$interaction_slider <- renderUI({
    sliderInput(
      "slider",
      "Select Range:",
      min = min(time(timeSeries)),
      max = max(time(timeSeries)),
      value = c(min, max)
    )
  })

  brks <- reactive({
    req(input$slider)
    seq(input$slider[1], input$slider[2], length.out = 10)
  })

  output$breaks <- brks
}
shinyApp(ui, server)
  • Remove part of the code that is independent with the error(e.g two lines starting with print(), timeSeres and df)

  • new server calls reduced:

datetime <- Sys.time() + (86400 * 0:10)

server <- function(input, output, session) {
  output$interaction_slider <- renderUI({
    sliderInput(
      "slider",
      "Select Range:",
      min   = min(datetime),
      max   = max(datetime),
      value = c(min, max)
    )
  })
  
  brks <- reactive({
    req(input$slider)
    seq(input$slider[1], input$slider[2], length.out = 10)
  })
  
  output$breaks <- brks
}
  • Next, the example uses a relatively sophisticated Shiny technique where the UI is generated in the server function.

  • But the renderUI() doesn’t use any reactive inputs, so it should work the UI. this leads to new UI that generate the error:

ui <- fluidPage(
  sliderInput("slider",
    "Select Range:",
    min   = min(datetime),
    max   = max(datetime),
    value = c(min, max)
  ),
  verbatimTextOutput("breaks")
)
#> Error: Type mismatch for `min`, `max`, and `value`.
#> i All values must have same type: either numeric, Date, or POSIXt.
  • looking at each of the inputs we’re feeding to min, max, and value to see where the problem is:
min(datetime)
#> [1] "2021-03-15 23:20:03 UTC"
max(datetime)
#> [1] "2021-03-25 23:20:03 UTC"
c(min, max)
#> [[1]]
#> function (..., na.rm = FALSE)  .Primitive("min")
#> 
#> [[2]]
#> function (..., na.rm = FALSE)  .Primitive("max")
  • Now the problem is obvious: we haven’t assigned min and max variables
ui <- fluidPage(
  sliderInput("slider",
    "Select Range:",
    min   = min(datetime),
    max   = max(datetime),
    value = range(datetime)
  ),
  verbatimTextOutput("breaks")
)