Slide 1

Slide 1 text

Using interactivity responsibly in pharma R/Pharma 2018 Joe Cheng RStudio, Inc. Shiny

Slide 2

Slide 2 text

What is Shiny? Inputs (sliders, checkboxes, dropdowns, textboxes…) R code (load, manipulate, model, predict, tabulate…) Outputs (tables, plots, JS widgets, file downloads…) • Arranged in a user interface you construct yourself • Deployable on a server, so users of your app only need a web browser—they have no direct experience of R

Slide 3

Slide 3 text

Shiny in Pharma • Lots of promise • Some significant challenges • Some of which are technical—hooray! • I’ll sketch out some ideas, not finished features • My talk today is inspired by people in this room • In some cases, uncomfortably so • Thanks to Adrian Waddell, Eric Nantz, Max Kuhn, Phil Bowsher, Xiao Ni

Slide 4

Slide 4 text

Big opportunities • Medium for communication between data scientists and scientists/doctors, replacing huge PDFs with thousands of plots/tables • Self-service exploration/analysis of SDTM/ADaM data • Filtering/variable selection • Drill down on outliers • Publish a statistical routine as an app—allow users to bring their own data

Slide 5

Slide 5 text

Tough requirements In pharma, an analysis that yields a useful result must be: • Traceable: How did we arrive at these results? Can we go back and see what we did? • Reproducible: Can we easily rerun the analysis that produced these results? • Transparent: Can the methods we used in our analysis be easily inspected for correctness/appropriateness? • Extensible: Can a collaborator arbitrarily modify/extend the analysis without having to start from scratch?

Slide 6

Slide 6 text

Impedance mismatch • When we analyze data by writing R code directly, we’re using a medium that naturally lends itself to being reproducible, transparent, extensible • Interactive applications inherently remove the user from the “how” something is done • From “Run these lines of R code in your RStudio session” to “Click this button and drag this slider” • Requires less expertise, but reproducibility, transparency, extensibility are quickly lost • If interactive applications could give us both the “what” and the “how”, we could have the best of both worlds

Slide 7

Slide 7 text

What I’ll focus on today • Going back to previous app states to re-run the analysis • Generating “standalone” R code that reproduces the analysis • Snapshotting/exporting outputs into a standalone document (PDF, Word doc)

Slide 8

Slide 8 text

Demo https://github.com/jcheng5/rpharma-demo app.R

Slide 9

Slide 9 text

Save/restore • For session save/restore, the difficult parts are the actual save and restore of application state • Fortunately, this is already implemented in Shiny as part of the bookmarkable state feature

Slide 10

Slide 10 text

Save/restore • The bookmarkable state feature has hooks that let us build our own save/restore UI on top. • For saving: • session$doBookmark(): Programmatically trigger bookmarking (i.e. the saving of state). • onBookmarked(): Called when a successful bookmark operation completes, with the newly created URL. We can write the URL, along with any metadata we want, to a database. • In this case, we wrote the date/time, user, user-provided description, screenshot

Slide 11

Slide 11 text

Save/restore • To implement restore UI, load metadata from the database and render as some kind of output • Simple list of links • DT (datatable) • HTML “card” view (used in our example) • Restoring just means navigating to the URL generated by the bookmarking operation

Slide 12

Slide 12 text

Save/restore • Shiny bookmarking can save/restore more than just the state of the inputs; it is extensible • Use onBookmark to save arbitrary application state • Use onRestore to apply state that was previously saved from onBookmark

Slide 13

Slide 13 text

Generating code What we want: • A working Shiny app • Exposes the underlying R code of an analysis • Have the generated code actually be readable/maintainable • Work even when the analysis code is quite dynamic; not just changing parameters, but steps/outputs being added/removed • Shouldn’t require any heroics from the app author • Have the Shiny app code actually be readable/maintainable

Slide 14

Slide 14 text

Generating code • Warning: Experimental! • A shift in mindset • Before: a graph of reactive expressions; each one runs code that produces a value • After: a graph of reactive expressions; each one runs code that generates code that produces a value • A reactive graph that generates “how” (code) instead of “what” (values)

Slide 15

Slide 15 text

Generating code • We need three concepts to get started: • Quoting • Unquoting • Substituting • Google “tidy evaluation in 5 min” for more

Slide 16

Slide 16 text

Demo https://github.com/jcheng5/rpharma-demo quoting.R

Slide 17

Slide 17 text

Generating code Before: r <- reactive({
 data %>% filter(age <= input$maxage)
 })
 # Yields data frame After: r_expr <- reactive({
 expr(data %>% filter(age <= !!input$maxage))
 })
 # Yields the code:
 # data %>% filter(age <= 30)

Slide 18

Slide 18 text

Generating code Before: r2 <- reactive({
 r() %>% head(input$nrows)
 })
 # Yields data frame After: r2_expr <- reactive({
 expr( !!r1_expr() %>% head( !!input$nrows))
 })
 # Yields the code:
 # data %>% filter(age <= 30) %>% head(12)

Slide 19

Slide 19 text

Using generated code • Execute with eval_clean(expr) • Similar to base ::eval, but uses a “clean” environment that is directly parented by the global environment • Turn to a string with format_tidy_code(expr) • Ideally we will use styler ::style_text() but I don’t currently like the way it wraps dplyr pipelines

Slide 20

Slide 20 text

Downloadable reports See make_report_bundle in utils.R • Dynamically generates .Rmd using knitr ::knit_expand (thanks Eric Nantz) • Add (caller-specified) additional files that are needed to reproduce the analysis (e.g. csv/rds snapshots of data) • Renders the .Rmd and bundles everything into a .zip for download

Slide 21

Slide 21 text

Next steps • Download the repo at https://github.com/jcheng5/ rpharma-demo and play with it • Would love feedback from advanced Shiny/Pharma folks whether these approaches work for their apps; you can reach me at joe@rstudio.com • Eventual goal would be to codify best practices (in the form of helper functions and Shiny modules) and put them in a new package

Slide 22

Slide 22 text

Thank you! (Questions?)