Before we start…

\(\rightarrow\) LAST SESSIONS ? BONUS material!

Once Shiny is covered, I like to extend to the realm of R capabilities:

  • geocomputation: handling maps - you can integrate them in Shiny!
  • third party data: retrieving sets fro APIs (e.g.: twitter) + a bit of text mining (always useful)
  • clustering & supervised learning: very powerful when used correctly

BUT: other options are possible:

  • Using chatGPT
  • Python integration in RStudio
  • inference, testing, Granger causality
  • open to suggestions: go on & propose!
  • mentoring: help on your projects (needed?, needed!)
  • a use case: a short tour on how I build small apps

Key reminder: basic data science functions (tidyverse)

  • data wrangling: select() keeps only some columns, filter() keeps rows depending on some conditions, mutate() creates new columns (see Session 1).
  • pivot tables: perform an analysis on subgroups to simplify the data. group_by() defines the groups and summarize() the indicator (usually: mean(something) or n()).
diamonds %>% 
  group_by(cut) %>%
  summarise(avg_size = mean(carat)) 

Look at column names:

diamonds %>%
  group_by(cut, clarity) %>%
  summarise(nb_diamonds = n(), 
            avg_price = mean(price) %>% round(2)) 

Key reminder: INSIGHT!

library(gapminder)
gapminder %>% 
    filter(year == 2007, continent == "Asia") %>%
    ggplot(aes(x = gdpPercap, y = lifeExp, color = country)) + 
    geom_point() + theme_minimal() + 
    guides(color = guide_legend(ncol = 3))

Key reminder: CARE about your audience! CLARITY!

gapminder %>% 
    filter(year == 2007, continent == "Asia") %>%
    ggplot(aes(x = country, y = lifeExp)) + 
    geom_col() + theme_minimal() 

DataViz Advice

  • USE COLOR ONLY IF THE NUMBER OF CATEGORIES IS SMALL (~10 max!)
  • MAKE SURE ALL PARTS OF YOUR GRAPHS ARE EASY TO READ

Conditional formatting

Conditional formatting: overview

Several options:

  • change the output attributes depending on the level of a value using if()!
  • code categorical variables with mutate() and ifelse();
  • display output under some condition via conditionalPanel().

Including these options are a bit costly in terms of code, but can add value for the user (could be used for password! \(\rightarrow\) exercise).

if(…){…} => always useful!

Include the condition inside the output module in the server.

output$box1 <- renderValueBox({
    prop <- round(mean(data()$Gender=="Women"), 2)      # Proportion of women
    if(prop < 0.2){colorbox <- "red"}                     # Low proportion: bad
    if(prop > 0.4){colorbox <- "green"}                   # Higher proportion: better
    if(prop >= 0.2 & prop <= 0.4){colorbox <- "yellow"}   # Intermediate proportion: meh
    valueBox(
        value = prop, 
        subtitle =  "Proportion of women",
        icon = icon("female", lib = "font-awesome"),
        color = colorbox,
        width = 4  # Width in Bootstrap mode: needs a column()!
    )
})

if_else(condition, true, false)

diamonds %>%
    mutate(size_category = if_else(carat < 0.8, "Small",
                                   if_else(carat > 1.5, "Big", "Medium"))) %>%
    select(carat, price, cut, clarity, size_category)

conditionalPanel

A relatively simple syntax:

dashboardSidebar( 
    radioButtons("show", "Show full data (below)",
                                     c("yes" = "yes",
                                       "no" = "no"))
),
dashboardBody(
    ###### NEW ELEMENTS HERE
    conditionalPanel(
        condition = "input.show == 'yes'", # CONDITION (strange syntax)
        DT::dataTableOutput("pt")          # If condition is true...
    )
)

Going further with shiny

Themes & styles

Many packages can help make your app groovy! Curated lists + book:

Examples:

Going further with html & CSS

First, super simple intros to HTML & CSS:
https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/HTML_basics https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/CSS_basics
In notebooks & Shiny: http://dataviz-2021.netlify.app/slides/w9p2.html

The source: https://mastering-shiny.org/advanced-ui.html
The fresh package (this one is important!):
https://cran.r-project.org/web/packages/fresh/vignettes/fresh.html
https://github.com/dreamRs/fresh
One example of indirect (non visibly CSS) formatting:

font_avenir <- list(     # This is a formatting variable for plots' fonts
    family = "Avenir",   # This font has a modern look
    size = 9,
    color = 'grey')

p <-  movies %>% ggplot(aes(x = duration, y = imdb_score)) + geom_point() 
ggplotly(p) %>%
    layout(title = "Movies", font = font_avenir) # The font avenir is defined above

Going further with ggplot

General overview: https://exts.ggplot2.tidyverse.org/gallery/

Going pro

Good looking tables: references

See also:
https://rfortherestofus.com/2019/11/how-to-make-beautiful-tables-in-r/ https://appsilon.com/forget-about-excel-use-r-shiny-packages-instead/

Going even further with Shiny (this never stops)

DashboardPlus & bs4Dash

Summary of important packages

In the maze of all packages, here is the ultimate shortlist:

  • bs4Dash for modern templates
  • thematic & bslib for global theming (shiny)
  • fresh for local theming (shinydashboard, bs4Dash)
  • gt & reactable for awesome tables.

Pick your favorites!

Deployment

Step 1: organize!

Once your app is ready:
\(>\) if your app is in .Rmd, copy-paste the code and put it a .R script
\(>\) CALL the file “app.R” any other choice may lead to errors!!!
\(>\) put all files in the same folder: app.R & data file!

Step 2: launch your app, and click on “publish”

Step 3: follow the flow

  • enter your login & password if/when prompted
  • find a short name for your app
  • select the correct files (app.R + dataset .RData)
  • the deployment usually takes some time (around 1 minute for my apps)

There is another way to proceed, using the rsconnect package and the function deployApp().
See https://shiny.rstudio.com/articles/shinyapps.html

This requires a token & a password.

Inside shinyapps

In the sidebar, in “Account”, there is a “Tokens” option.

Advanced topics

What are your questions?


A ‘bad’ question is better than no question (there are no bad questions).

This was the last pure Shiny session: ask for help if need be!


CODING an APP is HARD.

Your turn!

Two exercises:

  1. Deploy your app (or any one app).
  2. Pick any existing app and add textInput widget. The user must enter a password in this widget. If the password is correct, the body displays any kind of output (table, plot, etc.)