You may install the stable version from CRAN, or the development version using
remotes::install_github('rstudio/DT') if necessary (this website reflects the development version of DT):
## R version 3.6.2 (2019-12-12) ## Platform: x86_64-apple-darwin15.6.0 (64-bit) ## Running under: macOS Catalina 10.15.2 ## ## Locale: en_US.UTF-8 / en_US.UTF-8 / en_US.UTF-8 / C / en_US.UTF-8 / en_US.UTF-8 ## ## Package version: ## assertthat_0.2.1 base64enc_0.1.3 BH_18.104.22.168 ## cli_2.0.1 colorspace_1.4.1 crayon_1.3.4 ## crosstalk_1.0.0 digest_0.6.23 DT_0.11.6 ## ellipsis_0.3.0 fansi_0.4.1 farver_2.0.3 ## fastmap_1.0.1 ggplot2_3.2.1 glue_1.3.1 ## graphics_3.6.2 grDevices_3.6.2 grid_3.6.2 ## gtable_0.3.0 htmltools_0.4.0.9002 htmlwidgets_1.5.1 ## httpuv_1.5.2 jsonlite_1.6 labeling_0.3 ## later_1.0.0 lattice_0.20.38 lazyeval_0.2.2 ## lifecycle_0.1.0 magrittr_1.5 MASS_22.214.171.124 ## Matrix_1.2.18 methods_3.6.2 mgcv_1.8.31 ## mime_0.8 munsell_0.5.0 nlme_3.1.143 ## pillar_1.4.3 pkgconfig_2.0.3 plyr_1.8.5 ## promises_1.1.0 R6_2.4.1 RColorBrewer_1.1.2 ## Rcpp_1.0.3 reshape2_1.4.3 rlang_0.4.4 ## scales_1.1.0 shiny_126.96.36.19901 sourcetools_0.1.7 ## splines_3.6.2 stats_3.6.2 stringi_1.4.5 ## stringr_1.4.0 tibble_2.1.3 tools_3.6.2 ## utf8_1.1.4 utils_3.6.2 vctrs_0.2.2 ## viridisLite_0.3.0 withr_2.1.2 xtable_1.8.4 ## yaml_2.2.1
The main function in this package is
datatable(). It creates an HTML widget to display R data objects with DataTables.
datatable(data, options = list(), class = "display", callback = JS("return table;"), rownames, colnames, container, caption = NULL, filter = c("none", "bottom", "top"), escape = TRUE, style = "default", width = NULL, height = NULL, elementId = NULL, fillContainer = getOption("DT.fillContainer", NULL), autoHideNavigation = getOption("DT.autoHideNavigation", NULL), selection = c("multiple", "single", "none"), extensions = list(), plugins = NULL, editable = FALSE)
Here is a “hello world” example with zero configuration:
If you are familiar with DataTables already, you may use the
options argument to customize the table. See the page Options for details. Here we explain the rest of the arguments of the
class argument specifies the CSS classes of the table. The possible values can be found on the page of default styling options. The default value
display basically enables row striping, row highlighting on mouse over, row borders, and highlighting ordered columns. You can choose a different combination of CSS classes, such as
Currently, DT only supports the Bootstrap style besides the default style. You can use the argument
style = 'bootstrap' to enable the Bootstrap style, and adjust the table classes accordingly using Bootstrap table class names, such as
table-hover. Actually, DT will automatically adjust the class names even if you provided the DataTables class names such as
DT:::DT2BSClass('display') ##  "table table-striped table-hover" DT:::DT2BSClass(c('compact', 'cell-border')) ##  "table table-condensed table-bordered"
Note you can only use one style for all tables on one page. Please see this separate page for examples using the Bootstrap style.
You can enable table editing using the argument
?DT::datatable for its possible values). Then you will be able to double-click a cell to edit its value. It works in both client-side and server-side processing modes. Below are two client-side examples (also see a Shiny example with server-side processing):
If the data object has row names, they will be displayed as the first column of the table by default. You can suppress row names via the argument
rownames = FALSE, and you can also change row names by providing a different character vector to
Row names are essentialy a new column added to the original data (via
It is very important to remember this when using DataTables options.
datatable() shows the column names of the data in the table, and you can use a custom character vector for the table header. There are a few possibilities. The first one is, you provide a new character vector to completely replace the column names of the data, e.g.
# colnames(iris) is a character vector of length 5, and we replace it datatable(head(iris), colnames = c('Here', 'Are', 'Some', 'New', 'Names'))
This can be cumbersome if you only want to replace one or two names, and you do not want to provide a whole vector of names. Then here is the second possibility: you can provide a shorter numeric or character vector as the index vector to replace a subset of the column names. For example, if you only want the 2nd name to be
'A Nicer Name', you can use
datatable(..., colnames = c('A Nicer Name' = 2)); or if you want to replace the name
'A Better Name', you can use
colnames = c('A Better Name' = 'X5').
When you display row names of the data, its column name will be a white space by default. That is why you cannot see its column name. You can certainly choose to use a column name for rownames as well, e.g.
container argument allows you to provide a different table container to hold the table cells. By default, the container is generated from the column names. Below is an example of a custom table header:
# a custom table container sketch = htmltools::withTags(table( class = 'display', thead( tr( th(rowspan = 2, 'Species'), th(colspan = 2, 'Sepal'), th(colspan = 2, 'Petal') ), tr( lapply(rep(c('Length', 'Width'), 2), th) ) ) )) print(sketch)
<table class="display"> <thead> <tr> <th rowspan="2">Species</th> <th colspan="2">Sepal</th> <th colspan="2">Petal</th> </tr> <tr> <th>Length</th> <th>Width</th> <th>Length</th> <th>Width</th> </tr> </thead> </table>
# use rownames = FALSE here because we did not generate a cell for row names in # the header, and the header only contains five columns datatable(iris[1:20, c(5, 1:4)], container = sketch, rownames = FALSE)
You can also add a footer to the table container, and here is an example:
# a custom table with both header and footer sketch = htmltools::withTags(table( tableHeader(iris), tableFooter(iris) )) print(sketch)
<table> <thead> <tr> <th>Sepal.Length</th> <th>Sepal.Width</th> <th>Petal.Length</th> <th>Petal.Width</th> <th>Species</th> </tr> </thead> <tfoot> <tr> <th>Sepal.Length</th> <th>Sepal.Width</th> <th>Petal.Length</th> <th>Petal.Width</th> <th>Species</th> </tr> </tfoot> </table>
DataTables does not provide column filters by default. There is only a global filter (the search box on the top-right). We added a
filter argument in
datatable() to automatically generate column filters. By default, the filters are not shown since
filter = 'none'. You can enable these filters by
filter = 'top' or
'bottom', depending on whether you want to put the filters on the top or bottom of the table.
iris2 = iris[c(1:10, 51:60, 101:110), ] datatable(iris2, filter = 'top', options = list( pageLength = 5, autoWidth = TRUE ))
Depending on the type of a column, the filter control can be different. Initially, you see search boxes for all columns. When you click the search boxes, you may see different controls:
When you leave the initial search boxes, the controls will be hidden and the filtering values (if there are any) are stored in the boxes:
low ... high;
["value1", "value2", "value3"];
When a column is filtered, there will be a clear button in its search box, and you can click the button to clear the filter. If you do not want to use the controls, you can actually type in the search boxes directly, e.g. you may type
2 ... 5 to filter a numeric column, and the range of its slider will automatically adjusted to
[2, 5]. In case you find a search box too narrow and it is difficult to read the values in it, you may mouse over the box and its values will be displayed as a tooltip. See this example for how to hide the clear buttons, and use plain text input styles instead of Bootstrap.
Below is a simple example to demonstrate filters for character, date, and time columns:
d = data.frame( names = rownames(mtcars), date = as.Date('2015-03-23') + 1:32, time = as.POSIXct('2015-03-23 12:00:00', tz = 'UTC') + (1:32) * 5000, stringsAsFactors = FALSE ) str(d) ## 'data.frame': 32 obs. of 3 variables: ## $ names: chr "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ... ## $ date : Date, format: "2015-03-24" "2015-03-25" ... ## $ time : POSIXct, format: "2015-03-23 13:23:20" "2015-03-23 14:46:40" ... datatable(d, filter = 'bottom', options = list(pageLength = 5))
The position of column filters may be off when scrolling is enabled in the table, e.g. via the options
scrollY. The appearance may be affected by Shiny sliders, as reported in #49.
callback is only the body of the function):
After we initialize the table via the
.DataTable() method in DataTables, the DataTables instance is passed to this callback function. Below are a few more examples:
Please note this
callback argument is only an argument of the
datatable() function, and do not confuse it with the callbacks in the DataTables options. The purpose of this argument is to allow users to manipulate the DataTables object after its creation.
escape determines whether the HTML entities in the table are escaped or not. There can be potential security problems when the table is rendered in dynamic web applications such as Shiny if you do not escape them. Here is a quick example:
m = matrix(c( '<b>Bold</b>', '<em>Emphasize</em>', '<a href="http://rstudio.com">RStudio</a>', '<a href="#" onclick="alert(\'Hello World\');">Hello</a>' ), 2) colnames(m) = c('<span style="color:red">Column 1</span>', '<em>Column 2</em>') datatable(m) # escape = TRUE by default
FALSE, you can also specify which columns you want to escape, e.g.
datatable(m, escape = 1) # escape the first column datatable(m, escape = 2) # escape the second column datatable(m, escape = c(TRUE, FALSE)) # escape the first column colnames(m) = c('V1', 'V2') datatable(m, escape = 'V1')
Please be cautious when using row names with numeric column indices. Since the row names will become the first column in the display, you should increase the column indices by one, e.g.,