Vignette last complied on 2021-03-28. i2dash is licenced under MIT + file LICENSE.
Scientific communication and data visualization are important aspects to illustrate complex concepts and results from data analyses. R Markdown enables weaving together narrative text and code into rich and reproducible documents, that can also run interactive widgets from R Shiny. R Studio’s Flexdashboard introduces dashboards to publish a group of related data visualizations, tables, images and narrative text in row and column-based layouts. Both, R Markdown and R Studio’s Flexdashboard require authors to manually create Markdown documents and assemble content at the right position in the file. The R package i2dash provides classes and functionality to programatically create customized, web-based flexdashboards for data presentation, exploration and sharing. This enables users from different scientific disciplines to present their diverse data to the public in the form of organized dashboards. Dashboard content is organised in so-called components and can be added iteratively to the dashboard, i.e. as data or visualizations become available along the analysis pipeline. Components are reusable and can be distributed across different dashboard pages to organize scientific findings thematically. Ultimately, i2dash supports a wide range of R objects (e.g. ‘htmlwidgets’) and custom content generating functions as input and therefore integrates well into existing data analysis pipelines.
The package can be installed with the remotes library:
install.packages("i2dash", dependencies = TRUE)
or the development version:
remotes::install_git(url = "https://gitlab.gwdg.de/loosolab/software/i2dash.git", repos = BiocManager::repositories())
Once installed, the package can be loaded and attached to your current workspace as follows:
library(i2dash)
For this tutorial we need to install the following packages:
install.packages(c("leaflet", "plotly", "ggplot2", "RColorBrewer"))
i2dash introduces a new S4 class called i2dashboard
. We start by creating an instance of the i2dashboard
class and set some relevant parameters:
title
- the dashboard’s title, as it will appear in the left corner of the navigation bar.author
- the name of the dashboard author, it will also appear in the navigation bar.interactive
- if set to TRUE
a shiny-based dashboard will be created, otherwise a static HTML file.theme
- changes the appearance of the dashboard. A variety of themes are available at R Studio’s Flexdashboard or Semantic UI forest.datadir
- defines the directory where dashboard files are stored.i2dashboard(
title = "Dashboard title",
author = "John Doe",
interactive = FALSE,
theme = "yeti") -> dashboard
We can examine the i2dashboard
object by calling the object. The output shows the title of the dashboard, the number of saved pages and the number of components the page contains. By default the i2dashboard
object contains the ‘default’ page without any components.
dashboard
#> A flexdashboard with the title: Dashboard title
#> ... containing 1 pages:
#> ... the page 'default' with the title 'Default page' contains 0 components.
With several accessor methods, it is also possible to change the slots interactive
, author
, theme
, datadir
and title
of the i2dashboard
object retrospectively:
interactivity(dashboard) <- TRUE
datadir(dashboard) <- getwd()
theme(dashboard) <- "cosmo"
author(dashboard) <- "John Doe, MaxMustermann"
title(dashboard) <- "New dashboard title"
We next use the add_page()
function to add two pages to the dashboard
object. The first argument (page
) sets an unique page identifier that will be used later to add components to it. The title
defines a title of the page, which is shown in the navigation bar.
dashboard %<>%
add_page(
page = "page1",
title = "Page 1",
layout = "focal_left",
menu = NULL) %>%
add_page(
page = "page2",
title = "Page 2",
layout = "focal_left",
menu = NULL)
We can use the menu
parameter to group several pages under a common drop-down menu:
dashboard %<>%
add_page(
page = "page3",
title = "Lemurs",
layout = "focal_left",
menu = "Animals") %>%
add_page(
page = "page4",
title = "Tigers",
layout = "focal_left",
menu = "Animals")
We can remove a page using the remove_page()
function. The page
argument contains the unique page identifier of the page to be removed.
dashboard %<>%
remove_page(page = "page2")
Content can be added to pages using components. A component can be a R object itself (e.g. a widget from htmwlwidgets), a file path (e.g. to a markdown or image file) or a function that can be called to generate content. Htmlwidgets are interactive visualizations embedded in HTML. There is a wide variety of R packages that offer htmlwidgets, ranging from various plots, heatmaps, networks, tables, geographical maps to specialized charts. Thus, the content of the dashboards is not limited to specific disciplines and can be designed in a maximum variety of ways. We’ll use the add_component
function to explore several options and fill page1
iteratively with three R objects:
library(leaflet)
leaflet() %>%
addTiles() %>%
addMarkers(lng=174.768, lat=-36.852,
popup="The birthplace of R") -> leaftlet_map
dashboard %<>%
add_component(leaftlet_map,
page = "page1",
title = "A map from leaflet")
library(plotly)
plot_ly(mtcars, x = ~wt, y = ~mpg) -> plotly_object
library(ggplot2)
mtcars %>%
ggplot(aes(x=mpg)) +
geom_density(fill="darkgrey") -> ggplot2_object
dashboard %<>%
add_component(plotly_object,
page = "page1",
title = "A plot from plotly") %>%
add_component(ggplot2_object,
page = "page1",
title = "A plot from ggplot2")
This results in the following dashboard:
Custom text and images allow the dashboard developer to explain his findings, name sources or provide guidance to the reader. Text and images can be added to a page by calling the add_component
function with a file path. The function will include file paths ending with .[png|jpg|jpeg|gif]
as image content, and other files as text content:
# download the image & text or use the files in the package
dir.create("images")
dir.create("texts")
if(!file.exists("images/lemur.jpg")){
img <- "https://upload.wikimedia.org/wikipedia/commons/7/77/Lemurs.jpg"
download.file(img,'images/lemur.jpg', mode = 'wb')
}
if(!file.exists("texts/lemurs.md")){
text <- readLines("https://en.wikipedia.org/wiki/Lemuriformes")
cat(text[277],file="texts/lemurs.md",sep="\n")
}
dashboard %<>%
add_component(file.path("images/lemur.jpg"),
page = "page3",
title = "A picture of a Lemur") %>%
add_component(file.path("texts/lemurs.md"),
page = "page3",
title = "About Lemurs")
This results in the following dashboard:
Near unlimited flexibility comes from the ability to pass functions to add_component
. Functions can be used to generate content based on their parameters when they’re called. Lets create such a function:
text_generator <- function(dashboard, n) {
stringi::stri_rand_lipsum(nparagraphs = n) %>%
paste(collapse = "\n\n") -> content
paste0("### Generated content\n\n", content)
}
The function text_generator
from above can generate n
paragraphs of Lorem Ipsum upon calling. We can include it’s return as content:
dashboard %<>%
add_component(text_generator,
page = "page4",
n = 4)
When writing your own generating functions, please keep it mind to set the title
of the component within the function:
The linking of several components enables an improvement in the communication of the structure of high-dimensional data, which plays a big role in most scientific fields. When linking several components, the data of the two visualizations are connected to each other by queries. Thus the interactive manipulation, e.g. selecting data points, of a component is transferred to the associated component.The package plotly
enables us to link plotly charts in a client-side way (i.e., no special web server or callback to R is required). The following example demonstrates, how to link two plots together by using plotly. Here you can find a detailed explanation and further examples of the clint-sided linkink mechanism of plotly
.
First, we load the data and create an object of class crosstalk::SharedData
with the function highlight_key
. This enables to query the data.
# load the `txhousing` dataset
data(txhousing, package = "ggplot2")
# declare `city` as the SQL 'query by' column
tx <- highlight_key(txhousing, ~city)
Next, we initiate a plotly object (base
) with the data object. And create two further plots (time_series
and dot_plot
) based on the new plotly object.
# initiate a plotly object
base <- plot_ly(tx, color = I("black")) %>%
group_by(city)
# create a time series of median house price
time_series <- base %>%
group_by(city) %>%
add_lines(x = ~date, y = ~median)
dot_plot <- base %>%
summarise(miss = sum(is.na(median))) %>%
filter(miss > 0) %>%
add_markers(
x = ~miss,
y = ~forcats::fct_reorder(city, miss),
hoverinfo = "x+y"
) %>%
layout(
xaxis = list(title = "Number of months missing"),
yaxis = list(title = "")
)
Finally, we add a new page to our dashboard, create two components and provide the plotly
objects as input.
dashboard %<>%
add_page(page="page5", layout="2x2_grid", title = "Linked components") %>%
add_component(page="page5", component=dot_plot) %>%
add_component(page="page5", component=time_series)
This results in the following dashboard page. We can select a data point in the left component and the lines of the right plot will be colour highlightened according to the selection:
Data analysis often have certain experimental factors (e.g. year or category) that are included repeatedly in figure scales. When communicating findings from such analysis, it would be desirable to have consitent representation (e.g. by color) of those factors across different figures. In i2dash, we solve this problem by introducing colormaps. Colormaps can be used by components to look up color scales for experimental factors. Here, we briefly introduce how colormaps are added to the dashboard, but refer to the development vignette for further information.
Lets assume we have an experimental factor called year:
year <- factor(c(2014, 2014, 2015, 2017, 2019, 2019), levels = c(2014:2021))
To assign each level a color from the sequential greens palette from the RColorBrewer package, we create a character vector with the colors and assign the levels as names.
colors <- RColorBrewer::brewer.pal(8, "BuGn")
names(colors) <- levels(year)
The colormap can then be added to the dashboard. From there on, components can consume the colormap and use the desired colors for figure scales.
dashboard %<>%
add_colormap(map = colors,
name = "year")
At any point in time, and particular when data analysis is finished, the assemble
function can be used to generate representation of the dashboard in R markdown format. Using the pages
parameter, we can define which pages will be included in the output.
dashboard %>%
assemble(file = "MyDashboard.Rmd", pages = c("page1", "page3", "page4", "page5"))
The resulting R Markdown file can be run with shiny or rendered with rmarkdown. Alternatively, open the R Markdown file in RStudio and click on the “Knit”/ “Run Dockument” button.
sessionInfo()
#> R version 4.0.4 (2021-02-15)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 19042)
#>
#> Matrix products: default
#>
#> locale:
#> [1] LC_COLLATE=C LC_CTYPE=German_Germany.1252
#> [3] LC_MONETARY=German_Germany.1252 LC_NUMERIC=C
#> [5] LC_TIME=German_Germany.1252
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] plotly_4.9.3 ggplot2_3.3.3 leaflet_2.0.4.1 i2dash_0.2.3
#> [5] magrittr_2.0.1 BiocStyle_2.18.1
#>
#> loaded via a namespace (and not attached):
#> [1] tidyselect_1.1.0 xfun_0.20
#> [3] bslib_0.2.4 purrr_0.3.4
#> [5] colorspace_2.0-0 vctrs_0.3.6
#> [7] generics_0.1.0 htmltools_0.5.1.1
#> [9] viridisLite_0.3.0 yaml_2.2.1
#> [11] utf8_1.1.4 rlang_0.4.10
#> [13] jquerylib_0.1.3 pillar_1.5.1
#> [15] later_1.1.0.1 glue_1.4.2
#> [17] withr_2.4.1 flexdashboard_0.5.2
#> [19] lifecycle_1.0.0 stringr_1.4.0
#> [21] munsell_0.5.0 gtable_0.3.0
#> [23] htmlwidgets_1.5.3 codetools_0.2-18
#> [25] evaluate_0.14 knitr_1.31
#> [27] fastmap_1.1.0 httpuv_1.5.5
#> [29] crosstalk_1.1.1 fansi_0.4.2
#> [31] assertive.base_0.0-9 highr_0.8
#> [33] Rcpp_1.0.6 xtable_1.8-4
#> [35] promises_1.2.0.1 scales_1.1.1
#> [37] BiocManager_1.30.10 jsonlite_1.7.2
#> [39] mime_0.10 assertive.types_0.0-3
#> [41] assertive.properties_0.0-4 digest_0.6.27
#> [43] stringi_1.5.3 dplyr_1.0.5
#> [45] shiny_1.6.0 grid_4.0.4
#> [47] tools_4.0.4 ymlthis_0.1.3
#> [49] sass_0.3.1 lazyeval_0.2.2
#> [51] tibble_3.1.0 crayon_1.4.1
#> [53] tidyr_1.1.3 pkgconfig_2.0.3
#> [55] ellipsis_0.3.1 data.table_1.14.0
#> [57] rmarkdown_2.7 httr_1.4.2
#> [59] R6_2.5.0 assertive.sets_0.0-3
#> [61] compiler_4.0.4