From as_rtftables() to a plan
Source:vignettes/articles/plan-and-as-rtftables.Rmd
plan-and-as-rtftables.RmdIf you already write as_rtftables() calls, you already
know most of the plan. The display half of a plan does not add new
settings: each verb passes its arguments on to
as_rtftables(), rtftable(),
stub_cols(), set_col_header() or
paginate_cols(), under the same names. This article lists
where each as_rtftables() argument went, and shows how to
see the call a plan makes.
A plan on a table you already have
A plan does not have to start from an ARD. Given a data frame that is
already the table, table_plan() keeps it as it is and the
plan uses only its display half. This is a small laboratory summary in
the usual shape: a parameter, a statistic label, and one column per
arm.
Show code
lab <- data.frame(
PARAM = rep(c("ALT (U/L)", "AST (U/L)", "Creatinine (umol/L)"), each = 4),
STAT = rep(c("n", "Mean (SD)", "Median", "Min, Max"), 3),
Placebo = c("86", "17.6 (8.21)", "15.0", "6, 59",
"86", "22.4 (6.12)", "21.0", "11, 50",
"86", "95.3 (18.9)", "93.0", "58, 159"),
Active = c("168", "18.4 (9.03)", "16.0", "5, 71",
"168", "23.1 (7.40)", "22.0", "10, 66",
"168", "96.1 (20.2)", "94.0", "53, 177"))The same pages, written both ways:
Show code
by_hand <- as_rtftables(
lab,
group_by = "value", collapse_repeats = TRUE,
blank_rows = "between_groups", blank_row_end = TRUE,
max_rows = 10, split = "group_safe",
border = "tfl", read_meta = FALSE)
as_plan <- table_plan(lab) |>
plan_row_group(mode = "value", collapse = TRUE) |>
plan_blanks(where = "between_groups", last = TRUE) |>
plan_paginate_rows(max_rows = 10, split = "group_safe") |>
plan_style(border = "tfl") |>
plan_apply()Both give the same pages:
all.equal(by_hand, as_plan)
#> [1] TRUE
Neither names the group column. With group_by = "value",
a run of equal values in the first column is a group. A plan built from
an ARD names it for you: it is the outermost row key of
table_plan(rows = ).
The call a plan makes
plan_apply(plan, stage = "args") gives the arguments the
plan resolves to, without running anything. $rtf is the
as_rtftables() call:
Show code
p <- table_plan(lab) |>
plan_row_group(mode = "value", collapse = TRUE) |>
plan_blanks(where = "between_groups", last = TRUE) |>
plan_paginate_rows(max_rows = 10, split = "group_safe") |>
plan_style(border = "tfl")
str(plan_apply(p, "args")$rtf)#> List of 8
#> $ group_by : chr "value"
#> $ collapse_repeats: logi TRUE
#> $ blank_rows : chr "between_groups"
#> $ blank_row_end : logi TRUE
#> $ max_rows : num 10
#> $ split : chr "group_safe"
#> $ border : chr "tfl"
#> $ read_meta : logi FALSE
This is the quickest way to find which line of a long plan decided a setting. Every layer has been merged, so what you see is what runs.
Where each argument went
Pages
as_rtftables() |
Plan |
|---|---|
max_rows, split, split_rows,
min_group_rows, cont_label
|
plan_paginate_rows(max_rows, split, break_before, min_group_rows, cont_label)
(split_rows is break_before) |
split = "by_value", group_col
|
plan_paginate_group(col): a page per value |
page_by |
no verb; use plan_paginate_group() for a page per
value |
then paginate_cols(pages, ...)
|
plan_paginate_cols(at, cut_by, every, keep, col_header, fit, allow_span_break, order) |
Rows
as_rtftables() |
Plan |
|---|---|
group_by, collapse_repeats
|
plan_row_group(mode, collapse) |
group_col |
the outermost row key of table_plan(rows = );
plan_paginate_group(col = ) for a page split |
sort_by, sort_desc
|
plan_sort("KEY", "-OTHER"): a minus sign for
descending |
blank_rows, blank_row_first,
blank_row_end, count_blank_rows
|
plan_blanks(where, first, last, counted) |
drop_cols |
plan_hide(...); also keep = FALSE on
plan_sort() / plan_paginate_group()
|
stub (and the deprecated stub_vars,
stub_label, stub_indent,
stub_group_summary) |
plan_stub(vars, name, indent, group_summary) |
listing |
plan_listing(listing_col(...), ...) |
Columns and header
as_rtftables() / other |
Plan |
|---|---|
auto_width |
plan_columns(auto_width = ) |
rtftable(col_rel_width = ), row_title
|
plan_columns(widths = , row_title = ); named widths
follow the columns |
set_decimal_split(pages, cols = ) |
plan_columns(decimal = ) |
set_col_header(pages, header, values = ) |
plan_col_header(header, values) |
header_sep |
the separator of several cols keys:
plan_columns(sep = )
|
Look
as_rtftables() / other |
Plan |
|---|---|
border, align_count_pct, and
rtftable()’s font,
font_size_half_points, row_height_twips,
cell_valign, markup, … |
plan_style(), same names |
style = rtf_table_style(header = , body = , ...) |
plan_style(border_header = , border_body = , ...) |
style_header(), style_cols()
|
plan_cell_style(header = TRUE, ...),
plan_cell_style(cols = , ...)
|
style_zone() |
plan_style(border_* = ) |
rtftable(cell_styles = ), style_body() by
condition |
plan_cell_style(where = ~ ..., ...), or a formula
value |
as_rtftables(align_count_pct = TRUE) |
plan_style(align_count_pct = TRUE) |
fmt_numeric() on the data |
plan_digits(<column> = 2),
plan_digits(.rows = c(Mean = 1))
|
Handled for you
as_rtftables() |
In a plan |
|---|---|
read_meta |
FALSE: a table from an ARD is a plain data frame with
no adapter metadata |
na, cell_format
|
the cells are text already: plan_cells(na = ) for an
empty cell |
Rules that differ from a single call
A few things behave differently because a plan is built from layers:
-
A later layer wins for every setting except one.
plan_hide()adds: twoplan_hide()calls hide both columns, because a later one un-hiding the first would be a surprise. -
Contradictions are errors.
plan_paginate_group()withplan_paginate_rows(max_rows = )says both “a page per value” and “this many rows a page”. A single call would quietly ignoremax_rows. A plan stops and says which to drop. -
Declarations name columns, not positions.
plan_columns(widths = c(row_label = 4, .values = 2))andplan_cell_style(cols = "Placebo")still apply after a column is added or reordered..valuesstands for every value column.
When to stay with as_rtftables()
Both routes produce the same pages, so choose by what fits the program:
-
A table from gt, rtables, flextable and the like:
as_rtftables()reads the object’s own header, spans and styles. A plan starts from a data frame. - A table from an ARD: a plan. It fills the cells, reads the header populations from the ARD, and keeps a program short.
- A study with many tables in one house style: a plan. The style is a set of layers written once, and each table adds its own. tflspec can also save a plan to a workbook and build it again from there.
See Tables from an ARD and The plan verbs.