Rmarkdown Datatable



I have encountered a strange bug that I believe originates with some kind of scoping issue between data.table and purrr. When I try to purrr::map a vector of paths of Rmd files to the rmarkdown::render function, the rendering fails. Browse other questions tagged markdown github-flavored-markdown or ask your own question. How often do people actually copy and paste from Stack. R Markdown supports dozens of static and dynamic output formats including HTML, PDF, MS Word, Beamer, HTML5 slides, Tufte-style handouts, books, dashboards, shiny applications, scientific articles, websites, and more.

We are happy to announce a new package DT is available on CRAN now. DT is an interface to the JavaScript library DataTables based on the htmlwidgets framework, to present rectangular R data objects (such as data frames and matrices) as HTML tables. You can filter, search, and sort the data in the table. See http://rstudio.github.io/DT/ for the full documentation and examples of this package. To install the package, run

The main function in this package is datatable(), which returns a table widget that can be rendered in R Markdown documents, Shiny apps, and the R console. It is easy to customize the style (cell borders, row striping, and row highlighting, etc), theme (default or Bootstrap), row/column names, table caption, and so on.

DataTables Options

The DataTables library supports a large number of initialization options. Through DT, you can specify these options using a list in R. For example, we can disable searching, change the default page length from 10 to 5, and customize the length menu to use page lengths 5, 10, 15, and 20:

When you need to write literal JavaScript code in these options (e.g. the callback functions), you can use the JS() function. An example of the initComplete callback:

Being able to write JavaScript gives you full flexibility to customize the table. However, one of the goals of DT is to avoid writing JavaScript in your R scripts, and we hope users can express everything in pure R syntax, so we have provided a few R helper functions in DT that essentially generates JavaScript code for users to fulfill some common tasks, such as formatting table columns and cells.

Formatting Functions

The functions formatCurrency(), formatPercentage(), formatRound(), and formatDate() can be used to format table columns. For example, for a data frame with five columns A, B, C, D, and E, we format the columns A and C as euros, B as percentages (rounded to 2 decimal places), round D to 3 decimal places, and format E as date strings (the pipe operator %>% comes from the magrittr package):

It is also easy to style the table cells according to their values using the formatStyle() function. You can apply different CSS styles to cells, e.g. use bold font for those cells with Sepal.Length > 5, gray background for Sepal.Width <= 3.4 and yellow for Sepal.Width > 3.4, and so on. See the documentation page for these formatting functions for more information.

Server-side Processing

Interactions with the table can be processed either on the client side (using JavaScript in the web browser), or on the server side. Server-side processing is suitable for large data objects, since filtering, sorting, and pagination can be much faster in R than JavaScript in the browser. In theory, you can use any server-side processing language to process the data, and we have implemented it in R, which you can trivially enable by using DT in Shiny apps (the default mode is just server-side processing).

Rmarkdown Datatable Filter

Column Filters

DataTables does not come with column filters by default. It only provides a global search box. We have added filters for individual columns in DT, and you can enable column filters using the argument filter = 'top' or 'bottom' in datatable(). Currently, three types of filters are provided:

  • For numeric/date/time columns, range sliders are used to filter rows within ranges;

  • Mac os x mountain lion free download iso. For factor columns, selectize inputs are used to display all possible categories, and you can select multiple categories there (note you can also type in the box to search all categories);

  • For character columns, ordinary search boxes are used to match the values you typed in the boxes;

Insert

These filters are similar to the ones introduced in the RStudio 0.99 Data Viewer. Column filters work in both server-side and client-side processing modes. You can enable search result highlighting by the option searchHighlight = TRUE.

Datatable

Shiny

If you have used DataTables before in Shiny (i.e. the functions dataTableOutput() and renderDataTable()), it should be trivial to switch from Shiny to DT. DT has provided two functions of the same names, and the usage is very similar. Basically, all you have to do is to load DT after shiny, so that dataTableOutput() and renderDataTable() in DT can override the functions in shiny. If you want to be sure to use the functions in DT, you can add the prefix DT:: to these functions. We will deprecate dataTableOutput() and renderDataTable() in shiny eventually as DT becomes mature and stable.

As mentioned before, DT uses the server-side processing mode in shiny. To go back to client-side processing, you can use renderDataTable(data, server = FALSE).

The first argument of the function renderDataTable() can be either a data object (e.g. a data frame), or a table widget object (returned by datatable()). The latter form is useful when you need to further process the table widget, e.g. format certain columns or cells.

When a table is rendered in a Shiny app, you can obtain some information about the state of the table via the input object in Shiny. For example, for a table output dataTableOutput('foo'), the indices of the selected rows can be obtained from input$foo_rows_selected, and the indices of rows on the current page are available via input$foo_rows_current (live example). This page has more information about using DT in Shiny.

DataTables Extensions

DataTables has several extensions, and we have integrated all of them into DT. You may enable extensions via the extensions argument of datatable(). For example, you can reorder columns using the ColReorder extension, show/hide columns using the ColVis extension, fix certain columns on the left and/or right via FixedColumns when scrolling horizontally in the table, and so on. Please see the documentation page for extensions for details.

We hope you will enjoy this package, and please let us know if you have any questions, comments, or feature requests.

Background

In an earlier post April this year, I discussed using flexdashboard (with RMarkdown) as an appealing and practical R alternative to Excel-based reporting dashboards. Since it’s possible to (i) export these ‘flexdashboards’ as static HTML files that can be opened on practically any computer (virtually no dependencies), (ii) shared as attachments over emails, and (iii) run without relying on servers and Internet access, they rival ‘traditional’ Excel dashboards on portability. This is an advantage that you don’t really get with other dashboarding solutions such as Tableau and Shiny, as far as I’m aware.

Traditionally, people also like Excel dashboards for another reason, which is that all the data that is reported in the dashboard is usually self-contained and available in the Excel file in itself, provided that the source data within Excel isn’t hidden and protected. This enables any keen user to extract the source data to produce charts or analysis on their own “off-dashboard”. Moreover, having the data available within the dashboard itself helps with reproducibility, in the sense that one can more easily trace back the relationship between the source data and the reported analysis or visualisation.

In this post, I am going to share a trick on how to implement this feature within RMarkdown (and therefore means you can do this in flexdashboard) such that the users of your dashboards can export/download your source data. This will be implemented using the DT package created by RStudio, which provides an R interface to the JavaScript library DataTables.1

(Credits to Jonathan Ng for sharing this trick with me in the first place! His original video tutorial that first mentions this is available here)

Dt Package R

The DT package

In a nutshell, DT is a R package that enables the creation of interactive, pretty HTML tables with fancy features such as filter, search, scroll, pagination, and sort - to name a few. Since DT generates a html widget (e.g. just like what leaflet, rbokeh, and plotly do), it can be used in RMarkdown HTML outputs and Shiny dashboards. I’ve personally found DT very useful when creating RMarkdown documents (knitted to HTML) because it allows you to create professional-looking, business-ready interactive tables with literally only a couple of lines of code, and you can do this entirely in R without knowing any JavaScript. The other alternative packages that perform a similar job of producing quick and pretty HTML tables are formattable, knitr::kable() and kableExtra, but as far as I’m aware only DT allows you to add these ‘data download’ buttons that we are focussing on in this post.

Downloadable tables

What we are trying to get to is an interactive table with buttons that allow you to perform the following actions:

R Markdown Data Table Scroll

  • Copy to clipboard
  • Export to CSV
  • Export to Excel
  • Export to PDF
  • Print

Though you might only require only one or two of the above buttons, I’m going to go through an example that lets you do all five at the same time. The below is what the final output looks like, using the iris dataset, where the download options are shown at the top of the widget:

To see what the interactive version is like, click here.

The Solution

The main function from DT to create the interactive table is DT::datatable(). The first argument accepts a data frame, so this makes it easy to use it with dplyr / magrittr pipes. This is how we will create the above table, using the inbuilt iris dataset:

Rmarkdown Datatable

And here is a brief explanation for each of the arguments used in the above code:

  • extensions: this takes in a character vector of the names of DataTables plug-ins, but only plugins supported by the DT package can be used here. We’ll just put ‘Buttons’ here.

  • options: this argument is where you feed in all the additional customisation options, which is specified in a list.2 I usually think of these as ‘expanded features’ that aren’t / haven’t been built into the DT package yet, but are available in the ‘source’ JavaScript library DataTables.

    • dom: This argument defines the table control elements to appear on the page and in what order. Here, we have specified this to be Blfrtip, where:

      • B stands for buttons,

      • l for length changing input control,

      • f for filtering input,

      • r for processing display element,

      • t for the table,

      • i for table information summary,

      • and finally, p for pagination display.

      You may move the letters around to control for where the buttons are placed, where for instance lfrtipB would place the buttons at the very bottom of the widget.

    • buttons: you pass a character vector through to specify what buttons to actually display in the widget, where ‘copy’ stands for copy to clipboard, ‘csv’ stands for ‘export to csv’, etc.

    • lengthMenu: this allows you to specify display options for how many rows of data to display on each page. Here, I’ve passed a list through with two vectors, where the first specifies the page length values and the second the displayed options.

Try it out! Note that if you run this code in a R script, the table will open up in your Viewer Pane in RStudio, but you will need to run the code within a RMarkdown document in order to produce a share-able HTML output.

Create a function (for cleaner code)

I’ve wrapped the solution in a handy function called create_dt(), which just adds a bit of convenience as I can simply load this script at the beginning of a RMarkdown document and then call the function throughout the document, whenever I want to display the data and make them downloadable. Here it is:

You can customise this function to suit whatever needs you have for your project, but I find creating a function for the task of generating DT tables just makes the overall code cleaner, shorter, and easier to follow.

End notes

Hope you enjoyed this short vignette.

Rmarkdown

Do comment down below if you find this useful, or if you have any related ideas or suggestions you’d like to share. If you liked this post, please do check out my blog for more R and data science related content.

And have a Merry Christmas everyone!

  1. Not to be confused with the data.table package, which is practically a “super” package for fast data manipulation and wrangling.↩

  2. See https://datatables.net/reference/option/ for a full documentation of the options.↩