-
Notifications
You must be signed in to change notification settings - Fork 0
/
intro.qmd
137 lines (82 loc) · 9.39 KB
/
intro.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# Introduction {#sec-intro .unnumbered}
```{r}
#| eval: true
#| echo: false
#| include: false
source("_common.R")
"#3a506b"
```
The guiding principles throughout this book are:
1. Code files should be easy to find
2. Work should be easy to check and share
The principles above are heavily influenced by the Benjamin Franklin [quote](https://www.goodreads.com/quotes/175428-a-place-for-everything-everything-in-its-place#:~:text),
> *"A place for everything, everything in its place"*
And the de-cluttering methods popularized by [Marie Kondo](https://learn.konmari.com/?campaign=WPTidyTips),
> *"Ensuring that each one of your belongings has its own spot is the only way to maintain a tidy and clutter-free home. Clutter has nothing to do with what or how much you own – it’s the failure to put things back where they belong."*
## Packages help you
[Do future 'you' a favor.]{style='font-size: 1.15em; font-style: italic; font-weight: bold; color: #3a506b;'}
The first and obvious benefit to structuring your Shiny app as an R package is that it simplifies file and folder management. If every Shiny app project you develop is structured as an R package, it removes the time you spend manually creating directories (or re-orienting yourself to each project's structure).
If you're using Posit Workbench, the R package structure will give you access to a well-designed IDE for Shiny applications. Posit Workbench has tools to help develop and debug functions, create and run unit tests, store internal and external data, manage dependencies, and write help files and long-form documentation.
## Packages help them
[Assume someone else will read your code.]{style='font-size: 1.15em; font-style: italic; font-weight: bold; color: #3a506b;'}
It's safe to assume the code used to build Shiny apps being deployed to a production environment will be seen (and hopefully used) by others. R packages make sharing your hard work with your colleagues easier because it removes their need to figure out where everything is, how it all fits together, and how it all (hopefully) works.
R packages are designed for others to install and use in their R environment. Hence, packages are a standardized way of extending R's capabilities by adding new functionality (like developing Shiny apps!).
> "*a package [is] the fundamental unit of shareable, reusable, and reproducible R code.*" - [R Packages, 2ed](https://r-pkgs.org/)
```{r}
#| label: co_box_production
#| echo: false
#| results: asis
#| eval: true
co_box(
color = "g",
header = "What does it mean to 'put something into production?'",
contents = "
‘Production’ usually means passing the code from your personal development environment into your company's cloud-based server environment, which typically involves bundling your app in a structure that can be shared, installed, tested, and launched.
> '*I think the easiest way to think about it for me is that we develop a model in one computational environment--think of this as maybe your laptop or maybe you work in a server environment--still, it's in one place, and it turns out the software that you need to have installed there is about tuning, training, etc. **Putting something into production is getting it out of that computational environment and successfully carrying it over to a new computational environment.** For many people, this might be like a cloud computing environment. It might be some kind of server your organization has, and we need to take it, lift it, and then successfully have it working.*' - Julia Silge, [What is 'production' anyway? MLOps for the curious (SatRdays London 2023)](https://www.youtube.com/watch?v=Fe9Xq1ApVUM))
I've added emphasis and edited this for clarity.
",
fold = TRUE,
look = "minimal"
)
```
Making an effort to write clear and simple code is a courtesy to whoever reads your code next (which is typically future you). Clear and straightforward code is especially important for Shiny applications destined for deployment in a production environment. The standardized and widely accepted way to organize code in R is as an R package.[^intro-r-pkgs]
[^intro-r-pkgs]: David Neuzerling has a great [post](https://mdneuzerling.com/post/data-science-workflows/) on the benefits of structuring your project as a package
## Packages are scalable
[Great R packages solve common problems.]{style='font-size: 1.15em; font-style: italic; font-weight: bold; color: #3a506b;'}
Suppose you use R to perform analyses, design data visualizations, or build and run reports. If you currently use `source()` to load any utility functions to perform this work, I suggest putting those functions in a package. Doing this will help extend your mental model from the specific use cases (i.e., "*X code performs task Y*") to a model for their more general uses (i.e., "*X package performs tasks like Y*").
The beauty of an R package mental model is that you’ll inevitably notice the similarities across common problems. Creating packages that define and solve common problems in your workflow can sometimes be some of the most popular/valuable contributions (see [`datapasta`](https://milesmcbain.github.io/datapasta/) and [`reprex`](https://reprex.tidyverse.org/)).
## Packages to know
I highly recommend reading and bookmarking the [Shiny articles](https://shiny.posit.co/r/articles/) and the sites for the core package development tools:
1. [`devtools`](https://devtools.r-lib.org/)
2. [`pkgbuild`](https://pkgbuild.r-lib.org/)
3. [`pkgload`](https://pkgload.r-lib.org/)
4. [`rcmdcheck`](https://rcmdcheck.r-lib.org/)
5. [`revdepcheck`](https://revdepcheck.r-lib.org/)
6. [`roxygen2`](https://roxygen2.r-lib.org/)
7. [`remotes`](https://remotes.r-lib.org/)
8. [`sessioninfo`](https://sessioninfo.r-lib.org/)
9. [`usethis`](https://usethis.r-lib.org/)
<!--
[^intro-golem]
[^intro-golem]: [Engineering Production-Grade Shiny Apps](https://engineering-shiny.org/) and the [`golem` package](https://thinkr-open.github.io/golem/) assumes readers "*are comfortable with building an R package.*"
[^intro-mastering-shiny]
[^intro-mastering-shiny]: Mastering Shiny includes an example for *[converting](https://mastering-shiny.org/scaling-packaging.html?#converting-an-existing-app)* an existing application with `usethis::use_description()`, but not creating a new app-package (i.e., with `usethis::create_package()`).
:::: {.callout-important collapse="true" appearance='simple'}
### [`monthApp`]{style='font-size: 1.10em;'} from Mastering Shiny
::: {style='font-size: 1.05em; color: #696969;'}
If you happened to download or clone the [`monthApp`](https://github.com/hadley/monthApp) example from the [Packages Chapter](https://mastering-shiny.org/scaling-packaging.html), you may have notice a few things:[^pkgs-0]
1. `DESCRIPTION` contains additional fields that are not addressed.[^pkgs-1]
2. `monthApp.Rproj` has been configured to work with package.[^pkgs-2a]
3. `devtools::build()` ([<kbd>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>B</kbd>]{style="font-weight: bold; font-size: 0.90em"}) has been configured to have additional behaviors.[^pkgs-2b]
4. Dependency management is discussed briefly but not documented in the application.[^pkgs-3]
5. `monthApp` doesn't have any help files[^pkgs-4] or tests.[^pkgs-5]
[^pkgs-0]: The [Packages](https://mastering-shiny.org/scaling-packaging.html) chapter from [Mastering Shiny](https://mastering-shiny.org/) gets your '*toes into the water of package development*', but in my opinion, is probably not enough for you to get your shiny app project into an R package that's ready to be shipped into most production environments.
[^pkgs-1]: The [`DESCRIPTION`](https://github.com/hadley/monthApp/blob/master/DESCRIPTION) file in `monthApp` contains fields not included in the arguments passed to `usethis::use_description()` (these were added [separately](https://github.com/hadley/monthApp/commit/9899da4c89f4114a0611b415f4a329daeb753069)), and a few arguments can be adapted or removed to save time.
[^pkgs-2a]: The `.Rproj` file is the connection between the `DESCRIPTION` fields, the code in the `R/` folder, and the IDE's **Build** pane or “package development mode.” If you already have an `.Rproj` file in your shiny app project, you can activate these settings under **Tools** > **Project Options** > **Build Tools**.
[^pkgs-2b]: The [`monthApp.Rproj`](https://github.com/hadley/monthApp/blob/9899da4c89f4114a0611b415f4a329daeb753069/monthApp.Rproj#L22) file contains additional settings you can add with **Tools** > **Project Options** > **Build Tools**, then under **Generate documentation with Roxygen**, click **Configure** and select **Install and Restart**.
[^pkgs-3]: The [`NAMESPACE` file](https://github.com/hadley/monthApp/blob/master/NAMESPACE) is empty and the `Imports` field is missing from the [`DESCRIPTION`](https://github.com/hadley/monthApp/blob/master/DESCRIPTION) (although the chapter discusses [importing `shiny`](https://mastering-shiny.org/scaling-packaging.html#r-cmd-check)).
[^pkgs-4]: `roxygen2` is mentioned, but it's beyond the scope of [Mastering Shiny](https://mastering-shiny.org/), so for now just know `roxygen2` syntax is placed in the code below `R/` to create the help files and the `NAMESPACE`.
[^pkgs-5]: `monthApp` doesn't have the testing infrastructure provided by [`testthat`](https://testthat.r-lib.org/), but this can be quickly created using `usethis::use_testthat()` (and an entire chapter is dedicated to [testing](https://mastering-shiny.org/scaling-testing.html).
:::
::::
-->