Summary

I’ve built a number of Shiny apps in the past already. Even though they had a lot of common features, I found it difficult to migrate functionality from one to the next project. Often times, different data structure and variable names made it necessary it to re-write a large portion of the code. Fortunately, there are a number of tools available within the R framework (packages and concepts) which allow for a high level of reusability. Non-standard evaluation (NSE) for instance helps to keep the different components of an app apart. Thus, definitions, functions and data can be stored separately. This means defintions of plot layers can be kept very generic and universal. They’re only evaluated in the context of the data set (independet of the topic - weather data, fund perfomance or earnings data). Based on the packages supporting NSE, I was able to build a demo app, which reaches a high level of maintainability and reusability.

Feel free to contact me if you’re interested or go to the demo first. See figure 1 for a screenshot and some explanations of the controls. Please note that the visual appearance of the app is very basic - on purpose. The focus lay very much on the technology side and not on the UI design.

Design Concept

I strove for a strict split of following code items:

  • Definitions (global and UI specific)
  • Data (data, meta data)
  • Libraries (data filter, plot layers, plot axis, UI controls, etc.)
  • Functions (data retrival/processing, plot rendering)
  • UI/server code per se

Technology

These are the main components used for the demo app:

  • MySQL database hosted at Digitalocean
  • Shiny server hosted at Digitalocean
  • R packages for data retrieval: DBI, RMariaDB, dbplyr
  • R packages for data processing: dplyr, purrr, tidyr, lubridate, RcppRoll
  • R packages for plotting: ggplot2, ggrepel

Dyncamic Rendering of UI Controls

Rendering the UI controls on the server part of the app script has a number of advantages: Firstly, these items are reusable. Secondly, the controls can be updated based on user interaction. In the demo app, the UI is changed when the user selects a different report. Rendering the UI controls is fairly easy - one line of code.

# UI library
def.ui.data <- list(
  id.sma = list(
    ui.item = "selectInput", ui.var = "selected", p = list(label = "Station", selected = expr(def$id.sma), 
      choices = expr(set_names(ds$id_sma$id_sma, ds$id_sma$name)), multiple = T, selectize = T)
  ),
  code.var = list(
    ui.item = "checkboxGroupInput", ui.var = "selected", p = list(label = "Variable", selected = expr(def$code.var), 
      choiceValues = expr(ds$code_var$code_var), choiceNames = expr(ds$code_var$name_short), inline = T)
  ),
  time.span = list(
    ui.item = "selectInput", ui.var = "selected", p = list(label = "Time Span", selected = expr(def$time.span), 
      choices = expr(names(lib.scale)), multiple = F, selectize = F)
  )
)

# Render UI controls
output$uiData <- renderUI({ imap(def.ui.data, ~ exec(.x$ui.item, inputId = .y, !!!map(.x$p, eval_tidy, env = e))) })
 
# Update UI entries with custom function update_ui()
update_ui(session, def.ui.data, def)

Use of Reports

Finding the right data set can be cumbersome for the user. In the demo app there are 200+ stations, multiple parameters and different time periods available. To guide the user directly to relevant data set, a number of pre-defined reports are available. Selecting a report overrides the curremt data definitions, updates the UI controls and renders a new plot. The user can thereafter fine-tune the settings. The use of bookmarks would further improve the user experience.

Demo App

The availability of weather data through the open source policy comes in handy. MeteoSwiss surface observations are available through the opendata.swiss platform. The data set consists of some 200+ stations with an update interval of ten minutes. Demo

Figure 1: Screenshot of the UI. 1) Button 2) Report selection, 3) Station selection, 4) Parameter, 5) Time selection 6) Layer selection, 7) Plot output Figure 1: Screenshot of the UI. 1) Button 2) Report selection, 3) Station selection, 4) Parameter, 5) Time selection 6) Layer selection, 7) Plot output

Example Charts Rendered with the Demo App

Figure 2: 7-day-timeseries for basic meteorological parameters, 10-minute-observations and rolling mean (thick line). Figure 2: 7-day-timeseries for basic meteorological parameters, 10-minute-observations and rolling mean (thick line).
Figure 3: Comparison of two stations with a 24-hour-timeseries (relating to a particular weather phenomena called 'Möhlin-Jet'. Note the adjusted formatting of the time scale Figure 3: Comparison of two stations with a 24-hour-timeseries (relating to a particular weather phenomena called 'Möhlin-Jet'. Note the adjusted formatting of the time scale