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()
## x y
## 1 1 a
## 2 2 b
## 3 3 c
## 4 4 d
## 5 5 e
## 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
- Use
styler
package if you adopt tidyverse style guide
- Use
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