library(knitr)
# print everything as paged ----
knit_print.data.frame <- function (x, options, ...) {
rmarkdown::paged_table(x, options) |>
rmarkdown:::print.paged_df()
}
registerS3method("knit_print", "data.frame", knit_print.data.frame)Table printing demo
This code is meant to replicate (and extend) the df_print option in rmarkdown. The code for kable or paged tables is relatively simple, and I have created a more complex function that prints short tables with kableExtra::kable() and longer tables with DT::datatable(). You have to source in the file with the knit_print.data.frame() function for each page in a website or each chapter in a book.
Code
These functions should override knitr::knit_print() for data frames, but wasn’t working at all until I learned in the knit_print vignette that you have to use registerS3method().
df_print: paged
data.frame(x = rnorm(5), y = LETTERS[1:5])df_print: kable
library(knitr)
# print everything as kable ----
knit_print.data.frame <- function (x, options, ...) {
knitr::kable(x) |> knitr::knit_print(options, ...)
}
registerS3method("knit_print", "data.frame", knit_print.data.frame)data.frame(x = rnorm(5), y = LETTERS[1:5])| x | y |
|---|---|
| -0.9906570 | A |
| 0.2181923 | B |
| 1.0508325 | C |
| -1.3864300 | D |
| -0.6493202 | E |
df_print: custom
Prints tables with 10 or fewer rows using kableExtra::kable() and longer tables with DT::datatable() (unless overridden by options). Includes chunk options for:
- digits (defaults to
getOption("digits")) - rownames (defaults to FALSE)
- pageLength (defaults to 10)
- escape (defaults to TRUE)
- table.cap
library(knitr)
# useful function for options
`%||%` <- function(l, r) {
if (is.null(l)) r else l
}
# super-customised table printing ----
knit_print.data.frame <- function (x, options, ...) {
# get options
digits <- options$digits %||% getOption("digits")
rownames <- options$rownames %||% FALSE
pageLength <- options$pageLength %||% 10
escape <- options$escape %||% TRUE
caption <- options$table.cap
# use DT for longer tables in html
if (nrow(x) > pageLength & knitr::is_html_output()) {
numeric_cols <- sapply(x, is.numeric) |> which() |> names()
dt <- DT::datatable(x,
rownames = rownames,
caption = caption,
escape = escape,
width = "100%",
height = "auto",
options = list(pageLength = pageLength),
selection = "none")
if (length(numeric_cols) > 0) {
dt <- DT::formatRound(dt,
columns = numeric_cols,
digits = digits)
}
knitr::knit_print(dt, options)
} else {
# use kableExtra::kable for PDFs or shorter tables
k <- kableExtra::kable(x,
digits = digits,
row.names = rownames,
caption = caption,
escape = escape) |>
kableExtra::kable_styling(
full_width = options$full_width,
bootstrap_options = c("striped", "hover")
)
if (knitr::is_html_output()) {
k <- c("<div class=\"kable-table\">", k, "</div>") |>
paste(collapse = "\n")
}
knitr::asis_output(k)
}
}
registerS3method("knit_print", "data.frame", knit_print.data.frame)Test custom df_print
Make data.frame and tbl_df object with 5 and 26 rows.
df5 <- data.frame(x = rnorm(5), y = LETTERS[1:5])
df26 <- data.frame(x = rnorm(26), y = LETTERS)
tbl5 <- tibble::tibble(x = rnorm(5), y = LETTERS[1:5])
tbl26 <- tibble::tibble(x = rnorm(26), y = LETTERS)Should be displayed with kableExtra::kable().
df5| x | y |
|---|---|
| -0.6516320 | A |
| 0.5748103 | B |
| -0.2814253 | C |
| 0.4269321 | D |
| -0.8323578 | E |
Should be displayed with DT::datatable().
df26Should be displayed with kableExtra::kable()
tbl5| x | y |
|---|---|
| -0.9567718 | A |
| 0.1482874 | B |
| -0.3381620 | C |
| -0.1308482 | D |
| -0.8651306 | E |
Should be displayed with DT::datatable()
tbl26Option Tests
Testing options in the r chunk header.
Set the number of digits to display in numeric columns. Defaults to getOption("digits").
# digits = 3
tbl5| x | y |
|---|---|
| -0.957 | A |
| 0.148 | B |
| -0.338 | C |
| -0.131 | D |
| -0.865 | E |
# digits = 4
tbl26rownames are FALSE by default
# rownames = TRUE
tbl5| x | y | |
|---|---|---|
| 1 | -0.9567718 | A |
| 2 | 0.1482874 | B |
| 3 | -0.3381620 | C |
| 4 | -0.1308482 | D |
| 5 | -0.8651306 | E |
# rownames = TRUE
tbl26Table captions.
tbl5| x | y |
|---|---|
| -0.9567718 | A |
| 0.1482874 | B |
| -0.3381620 | C |
| -0.1308482 | D |
| -0.8651306 | E |
tbl26Set the page length for DT, if the table is <= to that, will display as kable.
# pageLength = 3, so should be a DT
tbl5# pageLength = 30, so should be a kable
tbl26| x | y |
|---|---|
| -0.4356147 | A |
| -1.3184376 | B |
| -0.9926614 | C |
| -0.3951119 | D |
| 0.3668848 | E |
| 2.0449062 | F |
| 1.4734182 | G |
| 1.9424873 | H |
| 1.3329930 | I |
| 0.3562878 | J |
| 1.1314351 | K |
| 1.4886727 | L |
| 1.0288225 | M |
| -0.2596033 | N |
| -1.2021970 | O |
| -1.5940632 | P |
| 1.9479486 | Q |
| -0.2073134 | R |
| -0.2618764 | S |
| -0.5530543 | T |
| -0.2590854 | U |
| 0.6115439 | V |
| 1.1033557 | W |
| -0.2893176 | X |
| -2.2715219 | Y |
| 0.4267168 | Z |
escape is TRUE by default. Set to FALSE to use html or latex in tables.
# escape = FALSE
tibble::tibble(styles = c("<i>italics</i>", "<b>bold</b>"))| styles |
|---|
| italics |
| bold |
# escape = FALSE
tibble::tibble(styles = rep(c("<i>italics</i>", "<b>bold</b>"), 10))For kable only, defaults to TRUE for html and FALSE for pdf.
# full_width = TRUE
tbl5| x | y |
|---|---|
| -0.9567718 | A |
| 0.1482874 | B |
| -0.3381620 | C |
| -0.1308482 | D |
| -0.8651306 | E |
# full_width = FALSE
tbl5| x | y |
|---|---|
| -0.9567718 | A |
| 0.1482874 | B |
| -0.3381620 | C |
| -0.1308482 | D |
| -0.8651306 | E |