## Load install libraries (install first if needed)
library(devtools)
library(usethis)
library(roxygen2)
## Create package
usethis::create_package("LOCALPATH/PKGNAME")
## Add dependencies, i.e. all the packages that are needed to run the package's functions. Here is a non exhaustive list
## + Shiny
usethis::use_package("bslib")
usethis::use_package("bsicons")
usethis::use_package("shiny")
usethis::use_package("shinyjs")
usethis::use_package("shinyWidgets")
usethis::use_package("shinyFiles")
usethis::use_package("shiny.i18n")
## + Tidyverse (Better to call packages individually)
usethis::use_package("magrittr")
usethis::use_package("readr")
usethis::use_package("tidyselect")
usethis::use_package("dplyr")
usethis::use_package("ggplot2")
usethis::use_package("tibble")
usethis::use_package("forcats")
usethis::use_package("purrr")
usethis::use_package("stringr")
usethis::use_package("rlang")
# usethis::use_package("tidyverse", type = "depends")
## + Geospatial
usethis::use_package("sf")
usethis::use_package("terra")
usethis::use_package("units")
## Add license
usethis::use_mit_license()
## Add github actions
usethis::use_github_action_check_standard()Shiny app as a package
Instructions to create a structured package around a shinyapp
Introduction
This tutorial lays out the main steps and provide R code to create a barebone shiny application shipped as a package. The main advantage of this approach is to make complex applications easier to read and to maintain, mainly thanks to:
- Forcing code documentation,
- Code splitting between analytical functions and shiny modules,
- Setting dependency package versions for ensuring the app will work even if dependency updates would break the package code.
- Combine R, Rstudio and Github for backup and easy shipping of the application’s package.
- Package automated checks for CRAN submission that are helpful to debug and improve the code.
- Package users can access the shiny application with 2 line codes (one to install the package, one to run the app).
The two main changes with non-package R code are:
Each function call from another package should be explicit, using
pkg::fct()instead oflibrary(pkg); fct().Functions created in the package should be documented with:
A short description of what the function does,
An explanation of each input variable,
An description of the function’s output
An example of the function in action
While potentially more time consuming at first, writing a complex shiny app code as a package makes it much easier to maintain and for other to understand and contribute.
This document is based on the following references:
- https://engineering-shiny.org/index.html
- https://r-pkgs.org/
- https://happygitwithr.com/
- https://rstudio.github.io/bslib/
- https://appsilon.github.io/shiny.i18n/articles/basics.html
- https://rstudio.github.io/crosstalk/using.html
The core steps of the package development are:
- Create a Github repository to host the application’s package
- Create a linked Rstudio project to the Github repository
- Create the package core files in the Rstudio project
- Copy/paste the function and module template files to the R project
- Develop the application functions (modules and analytical), going back and forth between these 4 actions:
- Edit the template files to customize the application
- Create / update new files / functions as necessary
- Load functions to the local environment, update documentation, run checks (resp.
load_all(),document()andcheck()from thedevtoolspackage) - Commit and push changes to the Github repository.
Setup
Github repository and R project
Abbreviations
Through this tutorial we will use the following names that should be replace with your own chosen names specific to your package. They are all caps to be easy to spot but should be small caps in your project.
PKGNAME: name of your package.
GHACCOUNT: Github account where the package repository is hosted.
shiny_run_APPNAME(): the function that will launch the core Shiny app of the package. APPNAME and PKGNAME could be the same.
Step-by-step
- Decide your package name.
- Create a Github repository with the package name as repository name.
- Ideally add a Readme during repo creation and a gitignore for R. A license can be done later.
- Setup connection between Github and Rstudio (see happy git with R in the reference list for detailed instructions).
- In Rstudio, create a new project, choose version control as type of project and link your Github repository (with
httpsorsshdepending on how you connected Rstudio and Github). - Commit and push the project to have Rstudio Rproj files sync with Github.
Core package files
Once you have a github repo and linked R project, the rest of the setup is done with R using functions from the devtools and usethis packages mostly.
You can either create a temporary R script or markdown/quarto document in your project to have the key functions ready to run or copy/paste from here to the console. The package creation functions shown in this section are needed only one time.
Here is a core set of instructions to setup your package:
Updating package content
These three functions can be run often after building/updating the package’s functions for analytics or the shiny app UI and server.
## Run often, as soon as you have a new function created or updated
devtools::load_all()
## Update function documentation
devtools::document()
## Runs checks to find errors in the code that prevent functions
## to work or notes that would make the package refused by CRAN.
## Useful for debugging
devtools::check()Once your package is ready for production, you can:
Install the package from local files
devtools::install()Install from Github
remotes::install_github("GHACCOUNT/PKGNAME")
Barebone App
File naming
Under the project R/ directory, there will be a combination of functions that process and analyse data, shiny modules functions and one main shiny app function. It is recommended to prefix the modules names and file names with 'mod_*_ui.R' and 'mod_*_server.R' and make the main shiny app function name and file name something like: 'shiny_run_*.R'.
Calculation functions can also be prefixed with fct_*.R to make then clearly visible from shiny related functions in R/ directory’s file names and to other packages functions in the code.
ShinyApp structure in the package shiny_run_APP() function
In this code minimal example, the app contains three modules, one for each page: home, tool and about.
A group of reactive values embedded in rv can pass on reactive objects between the modules.
For a navbar page style with a navigation bar for separating a landing page, a tool page and an about page with references, the following general structure works well.