Introduction to blockr for users

David Granjon (cynkra GmbH), Karma Tarap (BMS) and John Coene (The Y Company)

shiny homepage

shiny homepage corrected

Developing enterprise-grade dashboards isn’t easy

Commercial solutions

  • License cost 💲💲💲.
  • Not R specific.

💡 Introducing {blockr}

“Shiny’s WordPress” (John Coene, 2024)

  • Supermarket for data analysis with R.
  • No-Code dashboard builder …
  • Extendable by developers.
  • Collaborative tool.
  • Reproducible code.

blockr 101

Problem: palmer penguins plot

What penguin species has the largest flippers?

  • How can I produce this plot?

The stack: a data analysis recipe

Stack
data
data
Block 1
Data: dataset, browser, …
Block 2
Transform block: filter, select …
Block 3
Result/transform: plot, filter, …

Collection of instructions, blocks, from data import to wrangling/visualization.

Zoom on blocks: processing units

  • Blocks categories: import (data), transform data, visualize, …
  • Provided by developers (or us).

Example: transform blocks

flowchart TD
  blk_data_in(Input data)
  blk_data_out[Output]
  subgraph blk_block[Transform block]
    blk_field1(Field 1)
    blk_field2(Field 2)
    blk_field1 --> |interactivity| blk_expr
    blk_field2 --> |interactivity| blk_expr
    blk_expr(Expression)
    blk_res(result)
    blk_expr --> |evaluate| blk_res
  end
  blk_data_in --> blk_block --> blk_data_out

A transform block:

  • Takes input data.
  • Exposes interactive input to transform the data (select column, filter rows, …).
  • Returns the transformed data.

🧪 Exercise 1

Instructions:

  • Click on the + button (top right corner).
  • Add a palmer_penguins block. You may search in the list.
  • Add a new filter_block, selecting sex as column and female as value. Click on run.
  • Add a new ggplot_block. Select x and y wizely.
  • Add a new geompoint_block. You may change shape and color.
  • You can remove and re-add blocks as you like …
  • Export the stack code and try to run it.

How much code would it take with Shiny?

library(shiny)
library(bslib)
library(ggplot2)
library(palmerpenguins)

shinyApp(
  ui = page_fluid(
    layout_sidebar(
      sidebar = sidebar(
        radioButtons("sex", "Sex", unique(penguins$sex), "female"),
        selectInput(
          "xvar", 
          "X var", 
          colnames(dplyr::select(penguins, where(is.numeric))),
          "body_mass_g"
        ),
        selectInput(
          "yvar",
          "Y var",
          colnames(dplyr::select(penguins, where(is.numeric))),
          "flipper_length_mm"
        ),
        selectInput(
          "color",
          "Color and shape",
          colnames(dplyr::select(penguins, where(is.factor))),
          "species"
        )
      ),
      plotOutput("plot")
    )
  ),
  server = function(input, output, session) {
    output$plot <- renderPlot({
      penguins |>
        filter(sex == !!input$sex) |>
        ggplot(aes(x = !!input$xvar, y = !!input$yvar)) +
        geom_point(aes(color = !!input$color, shape = !!input$color), size = 2)
    })
  }
)

Changing the data, you also need to change the entire hardcoded server logic!

It’s much easier with blockr

library(blockr)
1new_stack(
2  data_block = new_dataset_block("penguins", "palmerpenguins"),
  filter_block = new_filter_block("sex", "female"),
3  plot_block = new_ggplot_block("body_mass_g", "flipper_length_mm"),
4  layer_block = new_geompoint_block("species", "species")
)
5serve_stack(stack)
1
Create the stack.
2
Import data.
3
Create the plot.
4
Add it a layer.
5
Serve a Shiny app.

🧪 Exercise 2: with pharma data

Instructions: distribution of age in demo dataset

  1. Add a customdata_block with demo as selected dataset.
  2. Add a ggplot_block with x as func and AGE as default_columns.
  3. Add a geomhistogram_block (you can leave default settings).
  4. Add a labs_block with title = "Distribution of Age", x = "Age (Years), y = "Count" as settings.
  5. Add a theme_block.
  6. Add a scalefillbrewer_block.

Connecting stacks: towards a dinner party

The workspace

flowchart TD
  subgraph LR workspace[Workspace]
    subgraph stack1[Stack]
      direction LR
      subgraph input_block[Block 1]
        input(Data: dataset, browser, ...)
      end
      subgraph transform_block[Block 2]
        transform(Transform block: filter, select ...)
      end
      subgraph output_block[Block 3]
        output(Result/transform: plot, filter, ...)
      end
      input_block --> |data| transform_block --> |data| output_block
    end
    subgraph stack2[Stack 2]
      stack1_data[Stack 1 data] --> |data| transform2[Transform]
    end
    stack1 --> |data| stack2
    subgraph stackn[Stack n]
      stacki_data[Stack i data] --> |data| transformn[Transform] --> |data| Visualize
    end
    stack2 ---> |... data| stackn
  end

Collection of recipes (stacks) to build a dashboard.

🧪 Exercise 3: share data between stacks

Instructions:

  • Click on Add stack.
  • From the new stack: click on + to add a new result_block.
  • Add a new filter_block to stack 1, with sex as column and female as value.
  • Notice how the result of the second stack changes.
  • Add a new ggplot_block.
  • Add a new geom_point block.

How do I create a workspace?

library(blockr)
# Creates an empty workspace
1set_workspace(
2  stack_1 = new_stack(),
  stack_2 = new_stack()
)
3serve_workspace(clear = FALSE)
1
Initialise.
2
Optional: add stacks.
3
Serve Shiny app.

🧪 Exercise 4: joining data

  1. Click on Add stack, then add it a customdata_block with lab data.

  2. Click on Add stack.

    1. Add a customdata_block with demo data.
    2. Add a join_block with Stack = "lab_data", type = "inner", by = c("STUDYID", "USUBJID")

🧪 Exercise 5: Hemoglobin by Visit plot

  1. Consider the previous 2 stacks (lab data merged with demo data).

  2. Click on Add stack, then add a result_block, targeting the hb_data stack:

    1. Add a ggplot_block with x = "VISIT" and y = "Mean" as aesthetics.
    2. Add a geompoint_block with func = c("color", "shape") and default_columns = c("ACTARM", "ACTARM").
    3. Add a geomerrorbar_block with ymin = ymin, ymax = ymax and color = ACTARM.
    4. Add a geomline_block with group = ACTARM and color = ACTARM.
    5. Add a labs_block with title = "Mean and SD of Hemoglobin by Visit", x = "Visit Label" and y = "Hemoglobin (g/dL)".
    6. Add a theme_block, selecting whatever theme you like.
    7. TBC…

How far can I go with blockr?