Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using Shiny responsibly in pharma

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Joe Cheng Joe Cheng
August 16, 2018

Using Shiny responsibly in pharma

Shiny is a package for turning analyses written in R into interactive web applications. This capability has obvious applications in pharma, as it lets R users build interactive apps for their collaborators to explore models or results, or to automate workflows. However, the interactivity of Shiny apps is a double-edged sword, as it introduces challenges to the traceability and reproducibility of your analysis. To use interactive applications in pharma responsibly, these challenges must be addressed. In this talk, I discuss some of the tools and techniques you can use in Shiny to deal with these challenges head-on.

Avatar for Joe Cheng

Joe Cheng

August 16, 2018

More Decks by Joe Cheng

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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
  4. 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?
  5. 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
  6. 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)
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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)
  13. Generating code • We need three concepts to get started:

    • Quoting • Unquoting • Substituting • Google “tidy evaluation in 5 min” for more
  14. 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)
  15. 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)
  16. 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
  17. 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
  18. 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 [email protected] • Eventual goal would be to codify best practices (in the form of helper functions and Shiny modules) and put them in a new package