Dynamically Generate Tabset Panels in Quarto HTML Documents
Description
render_tabset() takes a data frame as input and outputs the markdown that generates the tabset to stdout (console). Only works with Quarto HTML documents.
Columns to use as tabset labels. Internally passed to the select argument of subset(). Accepts raw column names, strings, numbers and logical values.
output_vars
Columns to display in each tabset panel. Internally passed to the select argument of subset(). Accepts raw column names, strings, numbers and logical values.
sort
Logical, whether to sort the data with tabset_vars. The default is TRUE. If FALSE, the tabset will be output in the original order of the data.
layout
NULL or a character vector of length 1 for specifying layout in tabset panel. If not NULL, layout must begin with at least three or more repetitions of ":" (e.g. ":::"). Closing div (e.g. ":::") is inserted automatically. See for details: https://quarto.org/docs/authoring/figures.html#complex-layouts.
heading_levels
NULL or a vector consisting of natural numbers and missing values. The length is equal to the number of columns specified in tabset_vars. This controls whether it is partially (or entirely) displayed as normal header instead of tabset.
If heading_levels is a NULL, all output is tabset.
If heading_levels is a vector of positive natural number, the elements of the vector correspond to the columns specified in tabset_vars.
If the element is integer, the tabset column is displayed as headers with their level, not tabset. (e.g. 2 means h2 header). Levels 1 to 6 are recommended. The reason is that quarto supports headers up to 6. 7 and above will also work, but they are displayed as normal text. In addition, considering the chapter format, it is preferable to gradually increase the level, as in 1, 2 and 3.
Write #| results: asis at the beginning of the chunk or results=‘asis’ in the chunk options.
If multiple tabset_vars are given, create nested tabsets.
For columns specified in output_vars, columns of type list are output with print() and normal columns are output with cat().
If tabset_vars or output_vars have "factor", "Date" and "POSIXt" columns, they are converted internally to character. This is to prevent it being displayed as numeric when cat() is executed. If sort = TRUE, sorting is performed before conversion to string.
Value
NULL invisibly. This function outputs the markdown that generates the tabset to stdout (console).
Limitations
layout is intended for simplified use cases and complex layouts may not work.
When outputting tables or figures that use JavaScript (such as {plotly}, {leaflet}, {DT}, {reactable}, etc.), it seems JavaScript dependencies need to be resolved. A simple solution is to wrap the output in htmltools::div() and create a dummy plot in another chunk. See the Get started for details.
When tabset_vars and output_vars have the following columns, they may not display well:
A column of type list contains a named vector or list (This is for output_vars. tabset_vars must not contain list columns).
Classes with their own printing methods, such as "difftime", "ts", .etc.
When specifying a list-type column that includes ggplot objects in output_vars, setting the chunk option echo: fenced may cause the plots to not display correctly.
References
As this function is focused on quickly and dynamically generating tabsets and chunks, it is difficult to customize it on a chunk-by-chunk basis. The regular way to dynamically create chunks is to use functions such as knitr::knit(), knitr::knit_child(), knitr::knit_expand(), etc. For more information on these, see the following links.
Heiss, Andrew. 2024. “Guide to Generating and Rendering Computational Markdown Content Programmatically with Quarto.” November 4, 2024. doi:https://doi.org/10.59350/pa44j-cc302.
library("quartabs")# sample datadf <-data.frame(group1 =c(rep("A", 3), rep("B", 3)),group2 =rep(c("X", "Y", "Z"), 2),value1 =1:6,value2 = letters[1:6])# Here are examples of the output before it is converted to tabset.# If you want it to actually work, in the .qmd file,# set `results='asis'` in the chunk options or# write `#| results: asis` at the beginning of the chunk.# Basic usagerender_tabset(df, group1, value1)
::: {.panel-tabset}
# A
1
# A
2
# A
3
# B
4
# B
5
# B
6
:::
# Nested tabset, two outputs side by side with a width of 1:1render_tabset( df,c(group1, group2),c(value1, value2),layout ="::: {layout-ncol=2}")
::: {.panel-tabset}
# A
::: {.panel-tabset}
## X
::: {layout-ncol=2}
1
a
:::
## Y
::: {layout-ncol=2}
2
b
:::
## Z
::: {layout-ncol=2}
3
c
:::
:::
# B
::: {.panel-tabset}
## X
::: {layout-ncol=2}
4
d
:::
## Y
::: {layout-ncol=2}
5
e
:::
## Z
::: {layout-ncol=2}
6
f
:::
:::
:::
# Use heading instead of tabsetrender_tabset( df,c(group1, group2), value1,heading_levels =c(2, 3))
## A
### X
1
### Y
2
### Z
3
## B
### X
4
### Y
5
### Z
6