library(knitr)
# print everything as paged ----
<- function (x, options, ...) {
knit_print.data.frame ::paged_table(x, options) |>
rmarkdown:::print.paged_df()
rmarkdown
}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 ----
<- function (x, options, ...) {
knit_print.data.frame ::kable(x) |> knitr::knit_print(options, ...)
knitr
}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 ----
<- function (x, options, ...) {
knit_print.data.frame # get options
<- options$digits %||% getOption("digits")
digits <- options$rownames %||% FALSE
rownames <- options$pageLength %||% 10
pageLength <- options$escape %||% TRUE
escape <- options$table.cap
caption
# use DT for longer tables in html
if (nrow(x) > pageLength & knitr::is_html_output()) {
<- sapply(x, is.numeric) |> which() |> names()
numeric_cols <- DT::datatable(x,
dt rownames = rownames,
caption = caption,
escape = escape,
width = "100%",
height = "auto",
options = list(pageLength = pageLength),
selection = "none")
if (length(numeric_cols) > 0) {
<- DT::formatRound(dt,
dt columns = numeric_cols,
digits = digits)
}::knit_print(dt, options)
knitrelse {
} # use kableExtra::kable for PDFs or shorter tables
<- kableExtra::kable(x,
k digits = digits,
row.names = rownames,
caption = caption,
escape = escape) |>
::kable_styling(
kableExtrafull_width = options$full_width,
bootstrap_options = c("striped", "hover")
)
if (knitr::is_html_output()) {
<- c("<div class=\"kable-table\">", k, "</div>") |>
k paste(collapse = "\n")
}
::asis_output(k)
knitr
}
}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.
<- data.frame(x = rnorm(5), y = LETTERS[1:5])
df5 <- data.frame(x = rnorm(26), y = LETTERS)
df26 <- tibble::tibble(x = rnorm(5), y = LETTERS[1:5])
tbl5 <- tibble::tibble(x = rnorm(26), y = LETTERS) tbl26
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()
.
df26
Should 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()
tbl26
Option 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
tbl26
rownames 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
tbl26
Table captions.
tbl5
x | y |
---|---|
-0.9567718 | A |
0.1482874 | B |
-0.3381620 | C |
-0.1308482 | D |
-0.8651306 | E |
tbl26
Set 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(styles = c("<i>italics</i>", "<b>bold</b>")) tibble
styles |
---|
italics |
bold |
# escape = FALSE
::tibble(styles = rep(c("<i>italics</i>", "<b>bold</b>"), 10)) tibble
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 |