There are several scenarios where a layer template may be useful. Some tables, like demographics tables, may have many layers that will all essentially look the same. Categorical variables will have the same count layer settings, and continuous variables will have the same desc layer settings. A template allows a user to build those settings once per layer, then reference the template when the Tplyr table is actually built. Another scenario might be building a set of company layer templates that are built for standard tables to reduce the footprint of code across analyses. In either of these cases, the idea is the reduce the amount of redundant code necessary to create a table.
Tplyr has already has a couple of mechanisms to reduce redundant
application of formats. For example,
vignettes('tplyr_options')
shows how the options
tplyr.count_layer_default_formats
,
tplyr.desc_layer_default_formats
, and
tplyr.shift_layer_default_formats
can be used to create
default format string settings. Additionally, you can set formats table
wide using set_count_layer_formats()
,
set_desc_layer_formats()
, or
set_shift_layer_formats()
. But what these functions and
options don’t allow you to do is pre-set and reuse the settings
for an entire layer, so all of the additional potential layer modifying
functions are ignored. This is where layer templates come in.
The functions new_layer_template()
and
use_template()
allow a user to create and use layer
templates. Layer templates allow a user to pre-build and reuse an entire
layer configuration, from the layer constructor down to all modifying
functions. Furthermore, users can specify parameters they may want to be
interchangeable. Additionally, layer templates are extensible, so a
template can be use and then further extended with additional layer
modifying functions.
Consider the following example:
new_layer_template(
"example_template",
group_count(...) %>%
set_format_strings(f_str("xx (xx%)", n, pct))
)
In this example, we’ve created a basic layer template. The template
is named “example_template”, and this is the name we’ll use to reference
the template when we want to use it. When the template is created, we
start with the function group_count(...)
. Note the use of
the ellipsis (i.e. ...
). This is a required part of a layer
template. Templates must start with a Tplyr layer
constructor, which is one of the function group_count()
,
group_desc()
, or group_shift()
. The ellipsis
is necessary because when the template is used, we are able to pass
arguments directly into the layer constructor. For example:
tplyr_table(tplyr_adsl, TRT01P) %>%
add_layer(
use_template("example_template", RACE, by=ETHNIC)
) %>%
build() %>%
kable()
row_label1 | row_label2 | var1_Placebo | var1_Xanomeline High Dose | var1_Xanomeline Low Dose | ord_layer_index | ord_layer_1 | ord_layer_2 |
---|---|---|---|---|---|---|---|
HISPANIC OR LATINO | AMERICAN INDIAN OR ALASKA NATIVE | 0 ( 0%) | 0 ( 0%) | 0 ( 0%) | 1 | 1 | 1 |
HISPANIC OR LATINO | BLACK OR AFRICAN AMERICAN | 0 ( 0%) | 0 ( 0%) | 0 ( 0%) | 1 | 1 | 2 |
HISPANIC OR LATINO | WHITE | 3 ( 3%) | 3 ( 4%) | 6 ( 7%) | 1 | 1 | 3 |
NOT HISPANIC OR LATINO | AMERICAN INDIAN OR ALASKA NATIVE | 0 ( 0%) | 1 ( 1%) | 0 ( 0%) | 1 | 2 | 1 |
NOT HISPANIC OR LATINO | BLACK OR AFRICAN AMERICAN | 8 ( 9%) | 9 (11%) | 6 ( 7%) | 1 | 2 | 2 |
NOT HISPANIC OR LATINO | WHITE | 75 (87%) | 71 (85%) | 72 (86%) | 1 | 2 | 3 |
Within use_template()
, the first parameter is the
template name. After that, we supply arguments as we normally would into
group_count()
, group_desc()
, or
group_shift()
. Additionally, note that our formats have
been applied just as they would be if we used
set_format_strings()
as specified in the template. Our
template was applied, the table built with all of the settings
appropriately.
An additional feature of layer templates is that they act just as any other function would in a Tplyr layer. This means that they’re also extensible and can be expanded on directly within a Tplyr table. For example:
tplyr_table(tplyr_adsl, TRT01P) %>%
add_layer(
use_template("example_template", RACE) %>%
add_total_row()
) %>%
build() %>%
kable()
row_label1 | var1_Placebo | var1_Xanomeline High Dose | var1_Xanomeline Low Dose | ord_layer_index | ord_layer_1 |
---|---|---|---|---|---|
AMERICAN INDIAN OR ALASKA NATIVE | 0 ( 0%) | 1 ( 1%) | 0 ( 0%) | 1 | 1 |
BLACK OR AFRICAN AMERICAN | 8 ( 9%) | 9 (11%) | 6 ( 7%) | 1 | 2 |
WHITE | 78 (91%) | 74 (88%) | 78 (93%) | 1 | 3 |
Total | 86 (100%) | 84 (100%) | 84 (100%) | 1 | 4 |
Here we show two things - first, that the we called the template
without the by variable argument from the previous example. This allows
a template to have some flexibility depending on the context of its
usage. Furthermore, we added the additional modifier function
add_total_row()
. In this example, we took the layer as
constructed by the template and then modified that layer further. This
may be useful if most but not all of a layer is reusable. The reusable
portions can be put in a template, and the rest added using normal
Tplyr syntax.
It’s also possible to add interchangeable parameters into a layer template beyond the group constructor arguments. But this requires some special syntax. Consider the following template:
new_layer_template("example_params",
group_count(...) %>%
set_format_strings(f_str("xx (xx.x%)", n, pct)) %>%
set_order_count_method({sort_meth}) %>%
set_ordering_cols({sort_col})
)
In this example, we create a template similar to the first example.
But now we add two more modifying functions,
set_order_count_method()
and
set_ordering_cols()
. Within these functions, we’ve supplied
interchangeable parameters to the template function, which are
sort_meth
and sort_col
. In a
Tplyr layer template, these parameters are supplied
using curly brackets (i.e. {}).
To specify these arguments when using the templater, we use the
use_template()
argument add_params
. For
example:
tplyr_table(tplyr_adsl, TRT01P) %>%
add_layer(
use_template('example_params', RACE, add_params =
list(
sort_meth = "bycount",
sort_col = Placebo
))
) %>%
build() %>%
kable()
row_label1 | var1_Placebo | var1_Xanomeline High Dose | var1_Xanomeline Low Dose | ord_layer_index | ord_layer_1 |
---|---|---|---|---|---|
AMERICAN INDIAN OR ALASKA NATIVE | 0 ( 0.0%) | 1 ( 1.2%) | 0 ( 0.0%) | 1 | 0 |
BLACK OR AFRICAN AMERICAN | 8 ( 9.3%) | 9 (10.7%) | 6 ( 7.1%) | 1 | 8 |
WHITE | 78 (90.7%) | 74 (88.1%) | 78 (92.9%) | 1 | 78 |
In the add_params
parameter, you must supply a list.
That list must also be named, where the element names (in this example,
sort_meth
and sort_col
) match the parameter
names in the template itself. If there’s any mismatch between a
template’s parameters and the parameters provided to
add_params
, you will encounter an error. The values
supplied to add_param
are then exactly the arguments that
you would supply to the matching field within the template (i.e. there’s
no extra quoting using quo()
necessary to pass a
symbol).
If you want to view any available templates in your session, use the
function get_layer_templates()
.
get_layer_templates()
#> $example_template
#> Template name: example_template
#> Template parameters: None
#> Template code:
#> {
#> group_count(...) %>% set_format_strings(f_str("xx (xx%)", n, pct))
#> }
#>
#> $example_params
#> Template name: example_params
#> Template parameters: sort_meth, sort_col
#> Template code:
#> {
#> group_count(...) %>% set_format_strings(f_str("xx (xx.x%)", n, pct)) %>% set_order_count_method({
#> sort_meth
#> }) %>% set_ordering_cols({
#> sort_col
#> })
#> }
You can view a specific template using
get_layer_template()
.
get_layer_template("example_params")
#> Template name: example_params
#> Template parameters: sort_meth, sort_col
#> Template code:
#> {
#> group_count(...) %>% set_format_strings(f_str("xx (xx.x%)", n, pct)) %>% set_order_count_method({
#> sort_meth
#> }) %>% set_ordering_cols({
#> sort_col
#> })
#> }
Note that layer templates are of class
tplyr_layer_template
. They additionally carry the attribute
params
that specifies which parameters are available in the
template, which can be seen in the output above.
Finally, if you want to remove a layer from your session, use the
function remove_layer_template()