Join the R Community at ShinyConf 2023

Diagnostic Information for R Shiny Apps: Appsilon’s Shiny.info Package


Updated: January 24, 2023.

At Appsilon, we thrive on supporting the open-source community with innovative open-source packages. As we have already mentioned at various R conferences, the typical cycle of our work is: identification of a repeating programming problem, solving it, wrapping it into a package, testing internally, and once we decide it’s useful, happily sharing it with the R community. This happened with shiny.semantic first and was followed by the release of shiny.router, shiny.collections, semantic.dashboard, and more recently shiny.i18n.

shiny.info is an open-source package for R Shiny that allows developers to display diagnostic information in a div located in the corner of a Shiny app. The package is available on the Comprehensive R Archive Network (CRAN) and you can make use of it simply by running the following command from the R console:

install.packages("shiny.info)

How to Display R Shiny Diagnostic Information with shiny.info

In our daily work, we came across a problem of debugging Shiny apps that often ended with a query: “Oh, but actually what version of the app are you using?”, or “Are you sure that you are in the proper branch?”. You could say there is no problem with checking that with code or with the terminal.  But… if you work with a UI expert or you make an A/B test, you’d rather have that information displayed somewhere in your Shiny app rather than switching back and forth to the console.

Shiny.info enables exactly that! It allows developers to display any diagnostic information they need in the div located in the app corner. We created some helper functions for you. But before diving into them, let’s first create a baseline R Shiny app. Simply copy the following code:

library(shiny)
library(shiny.info)

ui <- pageWithSidebar(
  headerPanel("Iris k-means clustering"),
  sidebarPanel(
    selectInput("xcol", "X Variable", names(iris)),
    selectInput("ycol", "Y Variable", names(iris),
      selected = names(iris)[[2]]
    ),
    numericInput("clusters", "Cluster count", 3,
      min = 1, max = 9
    )
  ),
  mainPanel(
    plotOutput("plot")
  )
)

server <- function(input, output) {
  selectedData <- reactive({
    iris[, c(input$xcol, input$ycol)]
  })

  clusters <- reactive({
    kmeans(selectedData(), input$clusters)
  })

  output$plot <- renderPlot({
    palette(c(
      "#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
      "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"
    ))

    par(mar = c(5.1, 4.1, 0, 1))
    plot(selectedData(),
      col = clusters()$cluster,
      pch = 20, cex = 3
    )
    points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
  })
}

shinyApp(ui = ui, server = server)

Here’s what the app looks like:

Image 1 – Shiny dashboard (starting point)

Let’s proceed with showing R Shiny Diagnostic information.

Current App Version

You can easily display the current version of the app from the global variable VERSION. Here, we’ll display it in the top right corner:

VERSION = "1.5.0"

ui <- tagList(
  shiny.info::version(position = "top right"),

  pageWithSidebar(
    headerPanel("Iris k-means clustering"),
    sidebarPanel(
      selectInput("xcol", "X Variable", names(iris)),
      selectInput("ycol", "Y Variable", names(iris),
                  selected = names(iris)[[2]]
      ),
      numericInput("clusters", "Cluster count", 3,
                   min = 1, max = 9
      )
    ),
    mainPanel(
      plotOutput("plot")
    )
  ) 
)

Image 2 – App version (top right)

Application Author

Another thing you can do is provide information about the application’s author and provide a link to their website. All of this is made possible with the convenient powered_by() function:

VERSION = "1.5.0"

ui <- tagList(
  shiny.info::version(position = "top right"),
  shiny.info::powered_by("Appsilon", "https://appsilon.com", position = "bottom right"),

  pageWithSidebar(
    headerPanel("Iris k-means clustering"),
    sidebarPanel(
      selectInput("xcol", "X Variable", names(iris)),
      selectInput("ycol", "Y Variable", names(iris),
                  selected = names(iris)[[2]]
      ),
      numericInput("clusters", "Cluster count", 3,
                   min = 1, max = 9
      )
    ),
    mainPanel(
      plotOutput("plot")
    )
  ) 
)

Image 3 – App powered by (bottom right)

Displaying Generic Messages

You’re not limited to displaying only “useful” diagnostic messages. You can write any message you want by using the display() function. Let’s see how to use it to display a string in the top left corner:

VERSION = "1.5.0"

ui <- tagList(
  shiny.info::version(position = "top right"),
  shiny.info::powered_by("Appsilon", "https://appsilon.com", position = "bottom right"),
  shiny.info::display("Dignostic info about this dashboard", position = "top left"),

  pageWithSidebar(
    headerPanel("Iris k-means clustering"),
    sidebarPanel(
      selectInput("xcol", "X Variable", names(iris)),
      selectInput("ycol", "Y Variable", names(iris),
                  selected = names(iris)[[2]]
      ),
      numericInput("clusters", "Cluster count", 3,
                   min = 1, max = 9
      )
    ),
    mainPanel(
      plotOutput("plot")
    )
  ) 
)

Image 4 – Diagnostic message (top left)

Showing Info Values

And finally, let’s take a peek into displaying info values. These are useful when you want to show reactive values in a more textual form. We’ll use it to display the column name currently passed for the X-axis. The actual logic takes place in the server() function, so don’t forget to update it:

VERSION = "1.5.0"

ui <- tagList(
  shiny.info::version(position = "top right"),
  shiny.info::powered_by("Appsilon", "https://appsilon.com", position = "bottom right"),
  shiny.info::display("Dignostic info about this dashboard", position = "top left"),
  shiny.info::info_value("test_info_value", position = "bottom left"),

  pageWithSidebar(
    headerPanel("Iris k-means clustering"),
    sidebarPanel(
      selectInput("xcol", "X Variable", names(iris)),
      selectInput("ycol", "Y Variable", names(iris),
                  selected = names(iris)[[2]]
      ),
      numericInput("clusters", "Cluster count", 3,
                   min = 1, max = 9
      )
    ),
    mainPanel(
      plotOutput("plot")
    )
  ) 
)

server <- function(input, output) {
  output$test_info_value <- shiny.info::render_info_value(input$xcol)
  ...
}

Image 5 – Test info value (bottom left)

Additional Examples

For more examples and documentation details, we encourage you to visit the shiny.info GitHub page. Please let us know in the comments what you think about this package. Alternatively, you can open Issues or PRs on our repository with any ideas for improvement. The package is still in its infancy, but we hope that it will be immediately useful for Shiny developers. Enjoy and add the info to your apps!

Want to learn more about shiny.info? Check out our follow-up article.


Follow Us for More