Konrad Konrad - 3 months ago 18
R Question

Shiny scoping rules - where to load libraries in modular architecture

With this question I'm only interested in obtaining some clarity on a best approach to using packages while working with a Shiny app. Despite the fact that, contrary to good practice on asking R-related questions, the question does not contain code or reproducible example, I hope that it touches on practical and relevant matters.

Problem



I'm working on a modular Shin app that has the following structure:


  • server.R
    - contains some key functions and first few initial graphics

  • ui.R
    - provides basic user interface framework

  • data
    - folder with some data files that are not sourced dynamically


    • list.csv
      - sample file with data

    • ...
      - other data files


  • functionsAndModules
    - folder with
    *.R
    files pertaining to functions and modules


    • functionCleanGeo.R
      - simple function cleaning some data frames of format:
      cleanDataFrame <- function(data) { ... return(cleanDta) }

    • moduleTimeSeries.R
      - module providing time series analysis doing the following things:


      • generating user interface

      • sourcing data

      • generating charts


    • ...R
      - other modules and functions saved as
      *.R
      files.




Libraries



What I would like to know is how to approach loading packages that would be most optimal for the app structure outlined above. In particular, I would like to know:


  1. When it's sufficient to load libraries only in
    global.R
    and when (if at all) it may be required to load libraries across module files and/or
    server.R
    /
    ui.r
    ?

    1.2. For example when using
    shinyTree
    package I load it in
    server.R
    and
    ui.R
    as, it is my understanding that this flows from examples. Modules and functions use
    dplyr
    /
    tidyr
    combination, would it be sufficient to load those packages in
    global.R
    ?

  2. My preferred method for loading packages looks like that:
    Vectorize(require)(package = c("ggvis", "SPARQL", "jsonlite", "dplyr", "tidyr", "magrittr"), character.only = TRUE)
    , will it work fine with the architecture described above?


Answer

Here my two cents:

  • Packages to load need to be declared at the start of the app.R file, at the server side of the app.R or alternatively at the modules file.
  • At the modules, the libraries can be declared either outside of the fooUI and fooServer module functions or inside. Both works.
  • For re-usability of the modules, I prefer to declare them at the start of each module*.R file.
  • At least for me, libraries loaded on the global.R file, do not get to the modules, so they can run. My hypothesis is that it doesn't load on the app.R environment. I understood that the global.R is to load share objects from serverand ui and to set some configuration.